Async wait for a function

前端 未结 2 1234
不思量自难忘°
不思量自难忘° 2020-12-12 06:23

I\'m trying to send an SMS for a function. But the problem is: The function takes about 10-15 seconds to finish (Since we do bunch of stuff with PhantomJS).

         


        
相关标签:
2条回答
  • 2020-12-12 06:39

    A quick and dirty solution that might work for you:

    var n = 0;
    _.each(users, function (userData) {
      setTimeout(function () {
        smsFree.sendSMSFree(userData, productUrl);
      }, 15000 * n++;
    });
    

    It runs the functions for every iteration with 15000 milliseconds (15 seconds) intervals between them. This is the only way that you can do it unless sendSMSFree either takes a callback or returns a promise.

    If it returns a promise (which it might, you didn't explain how that function works in your question) and you want to run them all at the same time but wait until all of them have finished - see the answer by Matías Fidemraizer.

    If you want to run them in series, i.e. run a new one as soon as the previous one finished, then it will be more complicated. If you want to add 15 second delay after the previous one finished before starting the next one, it will be more complicated still.

    If the function takes a callback, then you can use async.series.

    There's no point in explaining it in detail since we don't even know whether or not it returns a promise or takes callback at all - this is all speculation. You can see other answers that explain how promises and callbacks work if you're interested:

    • A detailed explanation on how to use callbacks and promises
    • Explanation on how to use promises in complex request handlers
    • An explanation of what a promise really is, on the example of AJAX requests
    • An explanation of callbacks, promises and how to access data returned asynchronously

    In summary:

    If the function that you call in the loop neither returns a promise nor takes a callback - then you can only add timeouts to delay them.

    If it returns a promise - you can use Q or Bluebird to control the flow.

    If it takes a callback - you can use async to control the flow.

    0 讨论(0)
  • 2020-12-12 06:47

    You should use promise pattern with Q. Your function should return a promise and things will be easier:

    Q.all(users.map(user => smsFree.sendSMSFree(userData, productUrl)))
           .then(() => {
               // Do stuff once every SMS has been successfully sent!
           }); 
    

    Or standard Promise:

    Promise.all(users.map(user => smsFree.sendSMSFree(userData, productUrl)))
           .then(() => {
               // Do stuff once every SMS has been successfully sent!
           }); 
    

    If your function doesn't use promise pattern you can either wrap it to use the whole pattern or you'll be stuck in terms of implement asynchronous continuations...

    0 讨论(0)
提交回复
热议问题