异步等待功能

时间:2016-11-22 12:04:03

标签: javascript node.js asynchronous

我正在尝试为某个功能发送短信。但问题是:该函数需要大约10-15秒才能完成(因为我们使用PhantomJS做了很多东西)。

_.each(users, function(userData){ // This does not work since i need to wait for 15 seconds
  smsFree.sendSMSFree(userData, productUrl);
});

我甚至尝试过使用setTimeout,但这种方式也不行。

我在NodeJS上。如何利用Async或其他库来解决我的问题?

我想等待15秒然后循环到第二个对象。不知道如何实现这一目标。 (Async.serial?)

  • - [R

2 个答案:

答案 0 :(得分:4)

您应该使用promise pattern with Q。您的函数应返回 promise ,事情会更容易:

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

或标准Promise

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

如果您的功能没有使用承诺模式,您可以将其包装为使用整个模式,否则您将陷入实现异步延续......

答案 1 :(得分:2)

可能为您工作的快速而肮脏的解决方案:

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

它为每次迭代运行函数,它们之间的间隔为15000毫秒(15秒)。这是你可以做到的唯一方法除非 sendSMSFree接受回调或返回承诺。

如果它返回一个promise(它可能,你没有解释你的问题中该函数是如何工作的)并且你想同时运行它们,但是等到所有这些都完成了 - 看看答案是MatíasFidemraizer。

如果你想连续运行它们,即在前一个完成后立即运行它们,那么它会更复杂。如果你想在上一个延迟之后加15秒延迟,然后开始下一个延迟,那么它将会更加复杂。

如果该函数采用回调,则可以使用async.series

没有必要详细解释它,因为我们甚至不知道它是否返回承诺或完全回调 - 这都是猜测。如果您有兴趣,可以看到解释承诺和回调如何工作的其他答案:

总结:

如果您在循环中调用的函数既不返回promise也不进行回调 - 那么您只能添加超时来延迟它们。

如果它返回一个承诺 - 您可以使用Q或Bluebird来控制流量。

如果需要回调 - 您可以使用异步来控制流量。