顺序运行Q Promises

时间:2015-09-22 06:10:37

标签: javascript node.js promise q

class Modulotest(models.Model): _inherit = 'account.invoice' @api.model def fields_view_get(self, view_id=None, view_type='form', toolbar=False): def get_view_id(xid, name): try: return self.env.ref('account.' + xid) except ValueError: view = self.env['ir.ui.view'].search([('name', '=', name)], limit=1) if not view: return False return view.id result = super(Modulotest, self).fields_view_get(view_id, view_type, toolbar=toolbar) if view_type == 'tree' and result['name'] == 'account.invoice.tree': currUtente = self.env.uid if currUtente.alt_view: result['arch'] = get_view_id('invoice_tree_inherit', 'account.invoice.tree.inherit').id return result class UtenteEsteso(models.Model): _inherit = 'res.users' alt_view = fields.Boolean("Vista alternativa", default=False) 应用中,我希望实现此目的: 读取数组,取决于项类型,决定使用返回Node.js Q对象的特定函数。我希望这个过程顺序运行。

我有两个承诺:

Promise

这是主要代码:

var q = require('q');
Classes.prototype.fn1 = function (item) {
    return q.Promise(function(resolve, reject){
        Items.find({item_published: true}).exec(
            function (err, events) {
                if (err) {
                    reject('an error happened');
                    throw err;
                }else{
                    resolve(events);
                }
        });
    });
};

Classes.prototype.fn2 = function (item) {
    return q.Promise(function(resolve, reject){
        resolve(item);
    });
};

但它不起作用。因为self.items = [{},{},{}]; //some items self.result = []; self.items.forEach(function(item,index,array){ if(item.type == 1){ self.fn1(item) .then(function(result){ self.result.push(result); }) } if(item.type == 2){ self.fn2(item) .then(function(result){ self.result.push(result); }) } if(index == array.length-1){ callback(self.result); } }); 具有异步过程,所以它在fn1之后运行。所有我想要的是顺序运行这些功能,即使其中一个具有异步过程。

3 个答案:

答案 0 :(得分:2)

您可以使用.reduce来链接承诺。

var promise = q(); // Create a Resolved promise for chaining.
self.items = [{},{},{}]; //some items
self.result = [];

// We put an resolved promise as init value for chaining
self.items.reduce(function(chain, item) {
    // Don't do anything if item type is not match
    if (item.type !== 1 && item.type !== 2) {
      return chain;
    }

    var targetFunc = null;
    if (item.type === 1) {
      targetFunc = self.fn1;
    } else if (item.type === 2) {
      targetFunc = self.fn2;
    }

    if (targetFunc === null) {
      return chain;
    }

    // Chain the promise and return the last of the chain.
    return chain
      .then(function(){
        return targetFunc(item);
      })
      .then(function(result){
        // This then will get the result from above
        // so we put the result to self.result here
        self.result.push(result);
      });
}, promise).then(function() {
  // When all promises are sequentially resolved,
  // call the callback with self.resul.
  callback(self.result);
});

jsfiddlejsfiddle-Q.js ver

答案 1 :(得分:1)

有一些非常类似于下面的烹饪......但是fuyushimoya太快了,尽管我们处理的是初始化不同的

var promises = self.items.map( function(item) {
    if (item.type == 2) {
      return self.fn1(item);
    }
    else if (item.type == 3) {
      return self.fn2(item);
    }
 });

function handler(p) {
  return p.then( function(res) {
    self.result.push(res);
  });
}

promises
 .reduce( function(prev, current) {
  if (prev) {
    return prev.then( function() { handler(current) } )
  } 
  else {
    return handler(current)
  }
})
 .then(function(result) {
    callback(null, result);
  })
  .catch( // error handler);

答案 2 :(得分:1)

草绘出来。但是这样的事情可能有用。

UPD:诀窍是链接承诺,就像评论中提到的那样,我用code snippet here更新了版本:

 var items = [{type:1},{type:2},{type:1}];
 var result = [];
 var rq = Q();
 var ql = rq;

 items.forEach(function (it, ix) {

    ql = ql.then(function(){
      var dp = "fn" + it.type;
      return ps[dp]();
    })
    .then(function(d) {
      result.push(d);
    });
 });

ql.then(function() {
  callback(result);
});