2

我正在开发一个小的 nodejs 程序,并且在知道程序的所有异步操作何时完成时遇到了一些麻烦。

目前,该程序执行以下步骤:

1/ 产生一个带有一些参数的进程。此过程将在其标准输出上打印数据。

2/ 监听进程标准输出“数据”事件,每次打印某些内容时,程序调用一个函数(我们将其称为“进程”),使用数据。

3/ 这个处理函数最终会将数据插入到一个mongo数据库中,并向一个amqp服务器发送一条消息。

3/ 当没有更多数据时,程序处于空闲状态,因为与 amqp 和 mongo 数据库的连接仍然存在,所以我需要知道所有工作何时完成才能关闭连接。

所以,我尝试使用when.js来利用 Promise,但我无法让它适用于我想要实现的目标。

我让“进程”函数返回一个承诺,当 mongodb 插入和 amqp 消息发送完成时,该承诺将得到解决。在我的程序中,我正在创建一个数组,它将接收所有能够调用 when.all() 以了解它们何时全部解决的承诺。

但是由于我在生成的进程正在将数据打印到其标准输出流时异步创建 Promise,所以对 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.

有没有办法让这个代码示例以预期的顺序打印控制台消息(第一行最后打印)?

谢谢。

4

1 回答 1

2

只有在做出所有承诺后,您才需要打电话。在您的评论中,您提到:

我想我不知道什么时候一切都以这种方式完成

这是不正确的。您可以使用事件知道一切何时完成close

ls.on('close',function(){
    when.all(promises).then(function (values) {
        console.log('All promises are now resolved', values);
    });
});
于 2013-12-11T19:29:46.937 回答