我正在尝试为某个功能发送短信。但问题是:该函数需要大约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?)
答案 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来控制流量。
如果需要回调 - 您可以使用异步来控制流量。