【问题标题】:Modify array object by async method under async forEach loop在 async forEach 循环下通过 async 方法修改数组对象
【发布时间】:2016-12-09 21:07:47
【问题描述】:

首先,我有一个users的数组,里面包含一些基本数据,比如

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

现在通过调用远程 API:self.getDrinks 对每个 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[],它总是报语法错误

【问题讨论】:

  • 用户将被更改,只是在您登录时不会更改
  • @JaromandaX 它只打印相同的原始users 而没有drinks[]。并且第 2 个 Logger 将在第 1 个 Logger 之前执行,因此用户最终不会有饮料[]。
  • 我的意思是用户修改了,只是在您登录this.users时没有-您声明他们不会更改-这是不正确的
  • 谢谢@JaromandaX,我修改了我的问题。

标签: javascript asynchronous typescript foreach callback


【解决方案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)));

【讨论】:

  • 因为我们的drinks 类型是一个数组。该代码将给出语法错误:Argument type Promise<TResut>[] is not assignable to parameter type iterableShim<PromiseLike<T>|T>
  • 这是对 Promise 可以解析的内容的打字稿限制吗?
  • 我从 Github 得到这个:link 但我认为它应该支持常见类型
  • 如果数组和 promise 有问题与此无关,因为任何 promise 都不知道饮料的数据类型。看代码。
  • 好的,因为它返回一个错误,你能想到的问题是什么?我认为Promise<TResult>[] 类型是说一些[] 在映射期间返回到Promise,然后再转换为iterableShim 可以接受的任何其他类型。
猜你喜欢
  • 2021-07-24
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
相关资源
最近更新 更多