如何在解决承诺的同时保持node.js脚本活动?

How to keep a node.js script alive while promises are being resolved?

我的脚本使用承诺(使用Q库)执行一些异步任务。运行Mocha测试工作正常。但是,从命令行运行脚本不会。节点进程立即终止。

1
2
3
4
5
var bot = require('./bot');

bot.getCategories().then(function (categories) {
  console.log('Found ' + categories.length + ' categories');
});


当没有更多的回调需要处理时,node.js将退出。可以使用setInterval或setTimeout始终保留一个,这样进程就不会自动退出。

1
2
3
4
5
function wait () {
   if (!EXITCONDITION)
        setTimeout(wait, 1000);
};
wait();

My script performs some asynchronous tasks using promises (with the q library). Running mocha tests works fine. However running the script from the command line does not. The node process immediately dies.

这肯定是一个错误,请务必报告它。当事件循环中仍有事物排队时,node.js环境不应过早退出。

你不应该为了实现这一点而改变你的代码。q库(请记住,现在有更多的现代和本地的替代方案)在process.nextTick的"微任务"队列上调度异步回调。您的bot库可能也会执行IO,这两种情况都会导致节点不终止。


我们从下面开始:

1
2
3
4
5
6
'use strict'

const timeoutPromise = (time) => {
    return new Promise((resolve, reject) => { setTimeout(() =>
        { console.log('howdy'); resolve('done') }, time) })
}

下面我们做…

结束a)-简单承诺

1
2
3
console.log('start')
timeoutPromise(1000)
console.log('end')

开始和结束将立即出现。再过一秒钟就可以看到"你好",并得到终端的提示。(所以在这个意义上,主脚本是活的,但大概不是操作人员想要的…)

结束b)-等待承诺回报

1
2
3
console.log('start')
return timeoutPromise(1000)
console.log('end')

"开始"将出现,1秒钟后将出现"howdy"。无法到达"结束"。所以在这里,我们真的在等待承诺,并且可以和他们一起做事情…

结束c)-然后())

1
2
3
4
5
6
console.log('start')
return timeoutPromise(1000).then((result) => {
        console.log('end', result)
        process.exit(123)  // usually 0 for 'ok', just demo!
    }
)

"开始"将出现,一秒钟后,"howdy"、"end"和"done"将出现。可用于发送返回值。

1
2
3
4
5
6
7
$>node haveMainWait.js
  start
  howdy
  end done

$>echo $?    // return value of last command
  123

几乎可以肯定的是,如果承诺被拒绝,你希望在.then()之后有一个.catch()。(仅在这种情况下返回非零退出代码)

当然,您可以使用Promise.all(…)或异步/等待函数(它必须包装成层次结构向上的某个地方的承诺),而不是像timeoutPromises(…)这样的单一承诺。你也在这里报道过。