我正在研究一个小的nodejs程序,并且有一些麻烦知道程序的所有异步操作何时完成。同步异步创建的承诺
现在,该程序执行下列步骤:
1 /产卵与一些参数的处理。此过程将在其stdout上打印数据。
2 /监听进程stdout“data”事件,每次打印某些内容时,程序都会使用这些数据调用一个函数(我们将称之为“进程”)。
3 /此过程函数最终将数据插入到mongo数据库并发送消息到amqp服务器。
3 /当没有更多的数据时,程序空闲,因为与amqp和mongo数据库的连接仍然存在,所以我需要知道何时完成所有工作才能关闭连接。
所以,我试图使用when.js来使用承诺,但我不能让它为我想要实现的目标而工作。
我让“process”函数返回一个promise,当mongodb insert和amqp消息发送完成后,这个promise就会被解析。 在我的程序中,我创建了一个数组,它将接收所有可以调用when.all()以了解它们何时全部解析的承诺。
但是,由于我在生成的进程将数据打印到其标准输出流时异步创建了承诺,所以对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.
有没有什么办法,使此代码以预期顺序(最后打印第一行)打印控制台消息样本?
谢谢。
把'when.all()'调用** **里面的'的setTimeout()'处理程序。 – Pointy
我不能这样做,否则它将不符合程序的实际代码,使用衍生进程并监听其标准输出“数据”事件。第二个setTimeout是对这个事件的模拟。在我的真实程序中,你必须想象这将被多次调用。多次调用when.all()来调用它没有意义吗?或者我错过了什么? –
在承诺存在之前调用'when.all()'没有任何意义。当您启动异步操作时,这些承诺会同步出现。我认为你的“测试”设置是真正的问题 - 你的'setTimeout()'调用本身没有返回一个承诺,而是一个真正的异步操作。 – Pointy