Search code examples
javascriptecmascript-6es6-promise

ES6 promise: wait for polling to finish to set var


I'm calling a polling function like so:

PollServer.getData(id)

It's a process that takes about 10 seconds and has a 30-second timeout. How can I assign in to a variable that'll wait for the timeout or the successful response (which is an array)?

This causes it to set the value immediately instead of waiting for the process:

var response = PollServer.getData(id)

And so does this:

fetch(PollServer.getData(id))
  .then(function(response) {
    console.log(`Final: ${response}`)
}).catch(function(error) {
  console.log(`Super error: ${error}`)
})

What am I missing?

Here's the PollServer class:

export class PollServer {
  static getData(id) {
    const token = process.env.SERVER_TOKEN,
          endpoint = `/documents/${id}`,
          request = `${endpoint}/request?token=${token}`,
          result = `${endpoint}/result?token=${token}`

    fetch(request, { method: 'get' })
      .then(function(response) {
        PollServer.poll(function() {
          return fetch(result, { method: 'get' })
        }, 30000, 500)
      .then(function(response) {
        console.log(`Finished: ${JSON.stringify(response)}`)
        return [response.low_url, response.high_url]
      })
    }).catch(function(error) {
      console.log(`Error: ${error}`)
    })
  }

  static poll(fn, timeout, interval) {
    var endTime = Number(new Date()) + (timeout || 2000)
    interval = interval || 100

    var checkCondition = function(resolve, reject) {
      var fetchCall = fn()
      fetchCall.then(function(response) {
        return response.json()
      }).then(function(response) {
        if (JSON.stringify(response.created) == 'true') {
          resolve(response)
        } else if (Number(new Date()) < endTime) {
          setTimeout(checkCondition, interval, resolve, reject)
        } else {
          reject(new Error(`Timeout: ${fn} with ${arguments}`))
        }
      })
    }
    return new Promise(checkCondition)
  }
}

Solution

  • So in light of this post I've solved my issue, which essentially is to return a Promise, a la:

    static getData(id) {
        const token = process.env.SERVER_TOKEN,
              endpoint = `/documents/${id}`,
              request = `${endpoint}/request?token=${token}`,
              result = `${endpoint}/result?token=${token}`
    
        return new Promise(function(resolve, reject) { // see here for what to do
          fetch(request, { method: 'get' })
            .then(function(response) {
              PollServer.poll(function() {
                return fetch(result, { method: 'get' })
              }, 30000, 500)
            .then(function(response) {
              resolve(response) // and resolve it here
            })
          }).catch(function(error) {
            reject(new Error(`Error: ${error}`))
          })
        })
    }