Loop through asynchronous request

so I have the following code to loop through a Object:

for(var x in block){
    sendTextMessage(block[x].text, sender, function(callback){
        //increment for?
    })
}

For each iteration I want to do a request (send a facebook message), only after that request has finished, I want to go through the next iteraction, this is because without any callbacks, the messages won't be sent in the right succession.

function sendTextMessage(text, sender, callback) {
    let messageData = { text:text}
    request({
        url: 'https://graph.facebook.com/v2.6/me/messages',
        qs: {access_token:token},
        method: 'POST',
        json: {
            recipient: {id:sender},
            message: messageData,
        }
    }, function(error, response, body) {
        if (response.statusCode >= 200 &&  response.statusCode < 300){
            if(callback) callback('success')
        }
    })
}

I've had this problem before and not been able to solve it, how can I, somehow do this?

If you have any questions, please ask. Thank you.


Solution 1:

You can use async module which will be really helpful to you for making requests one by one. Below is a sample code from async official docs which is fairly intuitive to understand.

  function asyncForEach (arr, iterator, callback) {
    queue = arr.slice(0)
        // create a recursive iterator
    function next (err) {
      if (err) return callback(err)

            // if the queue is empty, call the callback with no error
      if (queue.length === 0) return callback(null)

            // call the callback with our task
            // we pass `next` here so the task can let us know when to move on to the next task
      iterator(queue.shift(), next)
    }

        // start the loop;
    next()
  }

function sampleAsync (param, done) {
// put a callback when function is done its work 
}

  asyncForEach(result, function (param, done) { // result is the array you pass as iterator
    sampleAsync(param, function (message) {
      console.log(message)
      done()
    })
  }, function () {
    console.log('callback')
    callback(SOME_RESULT)
  })

}