如何在等待承诺完成时执行代码

时间:2017-03-20 20:47:24

标签: javascript node.js express promise co



我有一个明确的应用程序,我有一个需要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);
      });
    }

2 个答案:

答案 0 :(得分:0)

你的api本身不应该有这么重的阻塞功能。更好的方法是让另一个进程为您处理这种计算,因为节点是单线程的,这将阻止所有其他计算。确实有一些方法可以在一个线程/进程中通过在计算功能中添加超时来实现这一点,但这种风格并不是很好。由于我不知道你的功能是做什么的,因此很难给出一个可靠的答案。

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

答案 1 :(得分:0)

这不是很难实现:

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("...")); 

请注意,从根本上说,您应该将额外的工作放在工作队列中,并使用单独的流程来处理它。节点确实没有削减这种工作量。我建议查看替代方案的其他答案。