EventEmitter在一个Promises链中间

我正在做一些事情,包括按顺序运行一系列的child_process.spawn() (做一些设置,然后运行调用者感兴趣的实际命令,然后做一些清理)。

就像是:

 doAllTheThings() .then(function(exitStatus){ // all the things were done // and we've returned the exitStatus of // a command in the middle of a chain }); 

所有的doAllTheThings()都是这样的:

 function doAllTheThings() { runSetupCommand() .then(function(){ return runInterestingCommand(); }) .then(function(exitStatus){ return runTearDownCommand(exitStatus); // pass exitStatus along to return to caller }); } 

在内部我使用child_process.spawn() ,它返回一个EventEmitter ,我有效地从runInterestingCommand()返回close事件的结果返回给调用者。

现在我还需要将data事件从stdout和stderr发送到调用者,这些也来自EventEmitter。 有没有办法让(Bluebird)Promises这个工作,或者他们只是在阻碍EventEmitters发出多个事件?

理想情况下,我想能写:

 doAllTheThings() .on('stdout', function(data){ // process a chunk of received stdout data }) .on('stderr', function(data){ // process a chunk of received stderr data }) .then(function(exitStatus){ // all the things were done // and we've returned the exitStatus of // a command in the middle of a chain }); 

唯一可以考虑使我的程序工作的方法是重写它,以删除承诺链,并使用一个原始的EventEmitter里面的东西,包装设置/拆解,如:

 withTemporaryState(function(done){ var cmd = runInterestingCommand(); cmd.on('stdout', function(data){ // process a chunk of received stdout data }); cmd.on('stderr', function(data){ // process a chunk of received stderr data }); cmd.on('close', function(exitStatus){ // process the exitStatus done(); }); }); 

但是由于EventEmitter在Node.js中非常普遍,我不禁想到应该能够使它们在Promise链中工作。 任何线索?

其实,我想继续使用蓝鸟的原因之一,是因为我想使用取消function来允许从外部取消运行命令。

有两种方法,一种提供您最初要求的语法,另一种提供委托。

 function doAllTheThings(){ var com = runInterestingCommand(); var p = new Promise(function(resolve, reject){ com.on("close", resolve); com.on("error", reject); }); p.on = function(){ com.on.apply(com, arguments); return p; }; return p; } 

这会让你使用你想要的语法:

 doAllTheThings() .on('stdout', function(data){ // process a chunk of received stdout data }) .on('stderr', function(data){ // process a chunk of received stderr data }) .then(function(exitStatus){ // all the things were done // and we've returned the exitStatus of // a command in the middle of a chain }); 

然而,海事组织这是有些误导,可能需要通过代表:

 function doAllTheThings(onData, onErr){ var com = runInterestingCommand(); var p = new Promise(function(resolve, reject){ com.on("close", resolve); com.on("error", reject); }); com.on("stdout", onData).on("strerr", onErr); return p; } 

哪个可以让你做到:

 doAllTheThings(function(data){ // process a chunk of received stdout data }, function(data){ // process a chunk of received stderr data }) .then(function(exitStatus){ // all the things were done // and we've returned the exitStatus of // a command in the middle of a chain });