在async forEach循环下通过异步方法修改数组对象

时间:2016-08-04 00:06:45

标签: javascript asynchronous typescript foreach callback

首先,我有一个users数组,其中包含一些基本数据,例如

{"id": "1", "name": "a" }, {"id": "2", "name": "b" }

现在,通过为每个self.getDrinks调用远程API:user.id,它会返回一个新数组drinks[]。然后我想将drinks集成到每个用户中,最后它应该是:

{"id": "1", "name": "a", "drinks": [{"id": "1-1", "name": "coke"}, {"id": "1-2", "name": "orange"}]}, {"id": "2", "name": "b", "drinks": [{"id": "2-1", "name": "coke"}, {"id": "2-2", "name": "lime"}] }

我使用noSQL以便我必须执行异步函数来解析返回数据:

Result {
  result (object, optional),
  message (string, optional),
  error (integer, optional)
}

所以这是我的功能:

var self = this;
var itemsProcessed = 0;

this.users.forEach(function (user, idx, arr) {

  //assume the API getDrinks needs more parameters like below

  self.getDrinks(user.id, "getDrink", 0, 100, '', '', '', '', '') 
    .then((data: Result) => {
      itemsProcessed++;
      arr[idx].drinks = data.result.drinks;            
      }
      if (itemsProcessed === arr.length) {
        Logger.debug("Expected Result: " + JSON.stringify(arr));
      }
    })
    .catch(reason => Logger.error(reason));
});

Logger.debug("UnExpected Result: " + JSON.stringify(this.users));

正如您所看到的,最后我无法得到正确的this.users,因为它在forEach下的then函数中进行了修改。

有些人建议我使用Promise.all(),但由于返回类型是数组drinks[]

,它总是报告语法错误

1 个答案:

答案 0 :(得分:1)

使用promise.all,您应该能够将代码简化为以下内容:

Promise.all(this.users.map((user, idx, arr) => 
    this.getDrinks(user.id, "getDrink", 0, 100, '', '', '', '', '') 
    .then((data: Result) => {
        itemsProcessed++;
        user.drinks = data.result.drinks;            
    })
    .catch(reason => Logger.error(reason))
))
.then(() => Logger.debug("UnExpected Result: " + JSON.stringify(this.users)));