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 });