1

我有一个大致如下的代码(元 CoffeeScript):

xml = new ...
Promise.promisifyAll xml

allRecords = []
xml.on 'frequentTag', (item) ->
   ...

   iPromise = /* some promise made from item */

   allRecords.push iPromise

xml.onAsync('end').then -> Promise.settle allRecords

现在的问题是:我可以摆脱allRecords蓄电池吗?

4

1 回答 1

0

一个承诺代表一个单一的价值。这是一个值。

没有简单的方法来承诺事件发射器,因为它不提供标准合约,如单个值的节点样式回调 - 因为不同的事件被多次调用。

Promise.promisifyAll一个EventEmitter不会自己产生有意义的结果,你必须手动承诺它。好消息是,如果您碰巧经常这样做,您可以自己将其提取到一个函数中,或者使用 BluebirdpromisifyAll和一个 promisifier 参数并让它为您进行遍历。

Bluebird 不了解您的事件发射器以及它定义的关于何时调用回调以及如何调用的合同。假设它以事件结束,事件数据end的错误会随着error事件流入frequentTag- 我会做类似的事情:

xmlProto.prototype.getTags = function getTags(){
     // if you do this very often, this can be faster
     return new Promise(function(resolve, reject){ 
         var results = [];
         this.on("error", reject);
         this.on("frequentTag", function(item){
              iPhomise = /* some promise made from item */
              results.push(iPromise);
         });
         this.on("end", resolve.bind(null, results));
     }.bind(this)).settle(); // settle all
};

无论您在哪里 xmlProto new,这都可以让您这样做:

xml = new ...
xml.getTags().then(function(records){
    // work with records
});

这可以提取到这种事件发射器的通用函数中——但你明白了。

于 2014-09-29T06:14:57.593 回答