【问题标题】:Async wait for a function异步等待函数
【发布时间】:2017-04-06 02:23:35
【问题描述】:

我正在尝试为某个功能发送 SMS。但问题是:该函数大约需要 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 秒然后循环到第二个对象。不知道这是如何实现的。 (异步串行?)

  • R

【问题讨论】:

  • 如何判断函数何时结束?它会返回一个 Promise 吗?要求回电?
  • @MadaraUchiha 假设我的其他功能确实会回电。现在你能告诉我如何修改它以在循环其他对象之前等待吗?
  • 理想情况下,您需要了解承诺。在此之后,您可以使用隐藏在节点 V7 中的一些不错的功能,使用和谐开关。 async & await.

标签: javascript node.js asynchronous


【解决方案1】:

你应该使用promise patternwith 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!
       }); 

如果您的函数不使用 promise 模式,您可以将其包装以使用整个模式,否则您将在实现异步延续方面陷入困境......

【讨论】:

    【解决方案2】:

    可能适合您的快速而肮脏的解决方案:

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

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

    如果它返回一个承诺(它可能,您没有在您的问题中解释该函数是如何工作的)并且您想同时运行它们但要等到它们都完成 - 查看答案Matías Fidemraizer。

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

    如果函数需要回调,那么你可以使用async.series

    没有必要详细解释它,因为我们甚至不知道它是返回一个承诺还是接受回调——这都是猜测。如果您有兴趣,可以查看其他解释承诺和回调如何工作的答案:

    总结:

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

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

    如果需要回调 - 您可以使用 async 来控制流程。

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 1970-01-01
      • 2018-04-23
      • 2019-06-16
      • 2018-02-03
      相关资源
      最近更新 更多