AngularJS处理堆叠的promisses

时间:2016-04-05 02:20:21

标签: angularjs ionic-framework promise angular-promise

我有一组数组,我想运行异步。功能。

for(var a in As){

    this.doSomething(a).then(function(result){
        for(var b in Bs){
            this.somthingElse(b).then(function(){console.log(result)});
        }                   
    })
}

如何强制同步处理?我找到了Array.prototype.mapArray.prototype.reduce,但它们似乎在AngularJS中不可用?

4 个答案:

答案 0 :(得分:2)

首先,虽然AngularJS不包含angular.mapangular.reduce,但Array.prototype.mapArray.prototype.reduce与AngularJS基本无关。

任何现代浏览器都支持mapreduce数组函数。 angular.forEach用于兼容性目的(适用于IE8及更早版本)。如果您想使用map / reduce并支持IE8或更早版本,请尝试underscore.jslodash

回到你的问题,关于你想要达到的目标以及变量AsBs实际上是什么的信息不足。

让我们做出以下假设:

  1. AsBs都是合适的JavaScript阵列
  2. 对于As的每个成员,您希望doSomething使用它,等到它完成后,然后somthingElse与来自Bs的每个成员进行doSomething,完成后,记录somthingElse的结果
    • 这意味着您将运行As.length * Bs.length As次。
  3. 您不关心首先必须完成哪个As成员
    • 这意味着Bs成员将同时一起完成
  4. 同样,对于每次$q次迭代,您都不在乎谁先完成
  5. 以下是代码,您将需要Angular的// We cannot bring 'this' into map function's scope, so assign it to 'self' var self = this; var promises = As.map(function(a){ return self.doSomething(a).then(function(resultOfA){ return $q.all(Bs.map(function(b){ return self.somthingElse(b).then(function(resultOfB){ console.log(resultOfA); return resultOfB; // Not neccessary }); })) }); }); // Now if you want to do something after all those iterations, do it here: $q.all(promises).then(function(){ // do something after all 'As.length * Bs.length' iterations are done }); 服务:

    resultOfA

    您将在控制台日志中看到// We cannot bring 'this' into map function's scope, so assign it to 'self' var self = this; var promises = As.map(function(a){ return self.doSomething(a).then(function(resultOfA){ return $q.all(Bs.map(self.somthingElse)).then(function(resultsOfB){ return { resultOfA: resultOfA, resultsOfB: resultsOfB }; }); }) }); // Now if you want to do something after all those iterations, do it here: $q.all(promises).then(function(resultsOfA){ // do something after all 'As.length * Bs.length' iterations are done console.log(resultsOfA); // Output would be something like: // [{ // resultOfA: 'Result of A[0]', // resultsOfB: ['Result of B[0]', 'Result of B[1]', 'Result of B[2]...'] // }, { // resultOfA: 'Result of A[1]', // resultsOfB: ['Result of B[0]', 'Result of B[1]', 'Result of B[2]...'] // }] }); 的随机序列,暗示它们是异步完成的。如果您想获得实际结果以供日后使用,您可以改为:

    remove_user_from_channel(User, Channel=#channel_details{users = UserMap}) ->
        case maps:is_key(User, UserMap) of
            true -> Channel#channel_details{users = maps:remove(User, UserMap)};
            false -> ok
        end.
    

答案 1 :(得分:1)

你可以创建一个promises数组,然后使用$ q.all()来解决所有promises的完成。

var promises = [];
for(var a in As){
  promises.push(this.doSomething(a));
}

$q.all(promises).then(function(result){
  for(var b in Bs){
    this.somthingElse(b).then(function(){console.log(result)});
  }                   
})

答案 2 :(得分:1)

我认为您正在寻找一种同步运行所有内容的方法 - 所以如果您有以下内容:

var As = ['A1', 'A2', 'A3'];
var Bs = ['B1', 'B2', 'B3'];

您希望执行是' A1',' B1',' B2',' B3',& #39; A2',' B1',...

这是对的吗?

如果是这样,可以使用以下内容:

function start(){
  $log.log('start');
  As.reduce(function(promise, itemA){
    return promise.then(function(){
      return doSomething(itemA).then(startBs);
    });
  }, $q.resolve());
}

function startBs(){
  $log.log('start Bs');
  return Bs.reduce(function(promise, itemB){
    return promise.then(function(){
      return somethingElse(itemB);
    });
  }, $q.resolve());
}

样本plunker:https://plnkr.co/edit/fgiI3J2ylcW4FUXuXjIP?p=preview

答案 3 :(得分:0)

如果你可以使用bluebird,你可以这样做:

function doSomething(v){
    return new Promise(function(fullfil, reject){
      setTimeout(function(){
       console.log(v);
       fullfil(v);
      },500);
    });
};
 var As = [[1,2],[3,4],[5,6]];
(function start(){
  return Promise.map(As, function(a) {
        return doSomething(a).then(function(){
      return Promise.map(a, function(b) {
                    return doSomething(b);
    });
    });
});
})();