【问题标题】:How to execute code while waiting for a promise to finish如何在等待 Promise 完成时执行代码
【发布时间】:2017-08-12 07:47:28
【问题描述】:



我有一个快速应用程序,其中我有一个需要 aprox 的生成器函数。 5分钟处理大量数据。不幸的是,我无法优化该功能。
自动表达times out after 2 minutes,我确实想只为这个特定的功能改变它。我想如果我定期拨打res.write() 电话,2 分钟规则可能不适用。

我的问题:
如何在等待其他函数终止时每 X 秒执行一次 res.write('Something')

我希望它执行以下操作,希望您能理解。

    function main() {
      co(function* () {
        const something = yield promise(); // function that needs a lot of time
        const doWhileWaiting = setTimeout(() => {
          if (!something) {
            // Print this while waiting for the value of something
            console.log('Waiting for something ... ');
          } else {
            console.log(something);
            clearInterval(doWhileWaiting);
          }
        }, 5000);
      });
    }

【问题讨论】:

  • 您想让用户等待整整五分钟吗?您可以发送“谢谢,您的数据将在五分钟内准备好”之类的回复。并通过 webhook、web socket、推送通知等提供通知,或者只是给他们一个链接,让他们可以检查何时准备好。
  • 这是一个应用程序,最终服务器会每天执行一次脚本调用这个函数。问题是由于产量的原因,“某事”之后的所有内容在完成之前都不会被执行。有没有办法在后台执行它并在完成时收到通知?
  • 我认为你需要子进程...
  • 服务器每天执行一次脚本”到底是什么意思?您的意思是另一台服务器向您的端点发出 HTTP 请求吗?否则我看不出 express 与此有什么关系。

标签: javascript node.js express promise co


【解决方案1】:

这并不难实现:

const secret = Symbol();
const delay = ms => new Promise(r => setTimeout(() => r(secret), ms));

async waitFor(promise) {
    while(true) {
        const racer = await Promise.race(promise, delay(1));
        if(racer !== secret) return; // our promise won!
        await delay(100);
   }
}

此时,您需要添加一个操作,以便在它尚未完成时运行。

async waitFor(promise, action) {
    while(true) {
        const racer = await Promise.race(promise, delay(1));
        if(racer !== secret) return; // our promise won!
        await action(); // support passing a promise action.
        await delay(100);
   }
}

// will write to `res` every 100 ms while `yourPromise is not resolved.
waitFor(yourPromise, () => res.write("...")); 

请注意,从根本上说,您应该将额外的工作放在工作队列中,并使用单独的进程来处理它。 Node 真的不适合这种工作负载。我建议查看其他答案以获取替代方案。

【讨论】:

    【解决方案2】:

    您的 api 本身不应该有如此繁重的阻塞功能。更好的是让另一个进程为您处理这种计算,因为节点是单线程的,这将阻止所有其他计算。通过在计算函数中添加超时,肯定有办法在一个线程/进程中做到这一点,但这不是很好的风格。由于我不知道您的功能在做什么,因此很难给出一个可靠的答案,什么对您来说最好。

    正如你所说的它每天执行一次,你可以做一个 cronjob 触发另一个进程。如果您需要与您的 api 进程通信,您可能需要查看子进程。 https://nodejs.org/api/child_process.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 2021-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多