Q Promises - 在组1中运行所有承诺,然后在组2中运行,然后组N.

时间:2014-02-22 16:35:30

标签: promise q

我有许多承诺组,我只想在第1组中运行所有承诺,然后在所有成功时,第2组中的所有承诺等等到N组。

我的承诺都包含了传统的异步调用,因此我使用了Q的延迟功能:

createPromise: function (name, duration) {
   return function () {
       console.log('Executing ' + name);

       var deferred = Q.defer();
       setTimeout(function () {
           console.log(name + ' resolved');
           deferred.resolve();
       }, duration);
       return deferred.promise;
   };
},

以下是两组示例:

    var group1 = [
        this.createPromise('A', 5000), // 5 second delay
        this.createPromise('B', 6000)
    ];

    var group2 = [
        this.createPromise('1', 1000), // 1 second delay
        this.createPromise('2', 1000)
    ];

    var groups = [group1, group2];

我可以轻松地从第1组中运行单个项目,然后在第2组中运行单个项目:

    var q = Q();
    q = q.then(group1[0]);
    q = q.then(group2[0]);

输出:

Executing A
A resolved
Executing 1
1 resolved 

但我根本无法理解如何将第1组中的所有项目合并为一个承诺。

例如,在这种情况下,group1根本不运行 - 只执行group2的第一个项目。

    var q = Q();
    q = q.then(Q.all(group1));
    q = q.then(group2[0]);

2 个答案:

答案 0 :(得分:1)

我认为你的想法是正确的:

q.then(Q.all(group1));

然而,这有两个缺陷:

  • Q.all不接受一系列函数,而是一组promise。你需要做

     Q.all(group1.map(function(create) { return create(); }))
    
  • Q.all确实会返回一个承诺,但then确实需要稍后调用一个函数:

     q = q.then(function(prevGroupResult) {
          return Q.all(…groupN…);
     });
    

答案 1 :(得分:0)

您应该可以使用更多方法(在命名空间中)执行此操作:

  • runGroup :并行运行一系列函数
  • runGroupset :按顺序运行组数组。

这些功能将是这样的:

runGroup: function (group) {
    //Here we build an array of promises, on which `Q.all` can be applied
    var promises = [];
    for (var i = 0; i < group.length; i++) {
        promises.push(group[i]());
    }
    return Q.all(promises);
},
runGroupset: function (groupset) {
    //Here we build a then chain.
    var p = Q(true);//resolved promise
    for (var i = 0; i < groupset.length; i++) {
        p = p.then((function (i) {
            return function() {
                return myNamespace.runGroup(groupset[i]);
            }
        })(i));
    }
    return p;
}

使用如下:

var myGroupset = [];
myGroupset.push([
    this.createPromise('A', 5000), // 5 second delay
    this.createPromise('B', 6000)
]);
myGroupset.push([
    this.createPromise('1', 1000), // 1 second delay
    this.createPromise('2', 1000)
]);

myNamespace.runGroupset(myGroupset);

DEMO

修改

runGroupset已修改为在for循环中读取p = p.then(...)

编辑2

以上进一步更改,加上演示。