我正在研究一个小的nodejs程序,并且有一些麻烦要知道程序的所有异步操作何时完成。
目前,该计划执行以下步骤:
1 /使用一些参数生成进程。此过程将在其标准输出上打印数据。
2 /监听进程stdout“data”事件,每次打印一些东西,程序都会使用数据调用一个函数(我们称之为“进程”)。
3 /此进程函数最终将数据插入mongo数据库并向amqp服务器发送消息。
3 /当没有更多数据时,程序空闲,因为与amqp和mongo数据库的连接仍然存在,所以我需要知道所有工作何时完成才能关闭连接。
所以,我尝试使用when.js来使用promises,但我不能让它适用于我想要实现的目标。
我使“进程”函数返回一个promise,当mongodb insert和amqp message发送完成时将解析。 在我的程序中,我正在创建一个数组,该数组将接收所有可以调用when.all()以确定它们何时全部被解析的承诺。
但是,由于我在生成的进程将数据打印到stdout流时异步创建promises,因此使用空数组调用when.all(),这些数组似乎立即被解析。
这是一个代码示例,说明了我正在实现的目标:
var when = require('when')
, _ = require('lodash')
, cp = require('child_process');
var promises = [];
function process(data) {
var deferred = when.defer();
setTimeout(function () {
deferred.resolve(true);
}, 3000); // Let's say we need 3 seconds to process and save data
return deferred.promise;
}
var ls = cp.spawn('ls', ['-la', '/usr/bin']);
ls.stdout.on('data', function (data) {
console.log('Received data, creating a promise to notify when this data is processed.');
promises.push(process(data));
});
when.all(promises).then(function (values) {
console.log('All promises are now resolved', values);
});
正如您可能已经猜到的,该程序的输出是:
All promises are now resolved []
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
Received data, creating a promise to notify when this data is processed.
有没有办法按预期顺序(最后打印第一行)制作此代码示例打印控制台消息?
感谢。
答案 0 :(得分:2)
只有在完成所有承诺后才需要打电话。在您的评论中,您提到过:
我想我不知道什么时候这样做了
哪个不对。您可以知道何时使用close
事件完成所有操作:
ls.on('close',function(){
when.all(promises).then(function (values) {
console.log('All promises are now resolved', values);
});
});