首页 > 解决方案 > 在 For 循环中使用异步函数

问题描述

我有一个数组,我需要为每个索引调用一个 API 端点。解决后,我需要将其附加到该元素中。一旦完成数组的每个索引,我想返回更新的数组。

我尝试以这种方式使用 async-await

// Let input be [{'x': 1, 'y': 2}, {'x': 11, 'y': 22}, ...]

async function hello(input) {
  await input.forEach(element => {
     fetch(url, options)
     .then((res) => {
        element['z'] = res
     })  
  })
  return input
}

我需要使用这个函数来更新我的状态

hello(data)
.then((res: any) => {

    this.setState((prevState) => ({
        ...prevState,
        inputData: res,
    }))
})

问题是我需要一个更多的强制渲染来显示键“z”。如何解决这个问题?我没有太多使用异步等待的经验,所以我不确定我是否正确使用它。

标签: javascriptreactjsasync-await

解决方案


正确的方法是使用Promise.all并返回调用者函数使用的 promise,因为您希望将整个更新的输入值设置为 state。

在您的情况下, forEach 不会返回承诺,因此等待它是无用的。

此外,如果您在 forEach 函数中使用 await,您需要能够在所有承诺都解决后让 hello 函数的 .then 方法调用。Promise.all 为您做到这一点

function hello(input) {
  const promises = [];
  input.forEach(element => {
     promises.push(
          fetch(url, options)
             .then(res => res.json()
             .then((result) => { 
                // return the updated object
                return {...element, z: result};
              })
     ) 
  });
  return Promise.all(promises);
}

...
hello(data)
.then((res: any) => {
    this.setState((prevState) => ({
        ...prevState,
        inputData: res,
    }))
})

PS 请注意,来自 fetch 的响应也需要调用res.json()


推荐阅读