如何使用Array.prototype.map()的Async和Await?

56 阅读1分钟

使用async/await与map()的组合可能有点棘手。了解一下方法。

你想在一个map() 调用里面执行一个异步函数,对数组中的每个元素进行操作,并将结果取回。

如何才能做到这一点呢?

这就是正确的语法。

const list = [1, 2, 3, 4, 5] //...an array filled with values

const functionThatReturnsAPromise = item => { //a function that returns a promise
  return Promise.resolve('ok')
}

const doSomethingAsync = async item => {
  return functionThatReturnsAPromise(item)
}

const getData = async () => {
  return Promise.all(list.map(item => doSomethingAsync(item)))
}

getData().then(data => {
  console.log(data)
})

主要要注意的是使用Promise.all() ,当它的所有承诺被解决时,它就会被解决。

list.map() 返回一个承诺的列表,所以在 ,当我们运行的所有东西都被解决时,我们将得到这个值。result

记住,我们必须将任何调用await 的代码包在一个async 函数中。

关于承诺的更多信息,请参见承诺文章,以及async/await指南

使用这些占位函数名称可能很难将例子形象化,所以如何使用这种技术的一个简单例子是我为一个Twitter克隆写的这个Prisma数据删除函数,首先删除tweets,然后是用户。

export const clearData = async (prisma) => {
  const users = await prisma.user.findMany({})
  const tweets = await prisma.tweet.findMany({})

  const deleteUser = async (user) => {
    return await prisma.user.delete({
      where: { id: user.id }
    })
  }
  const deleteTweet = async (tweet) => {
    return await prisma.tweet.delete({
      where: { id: tweet.id }
    })
  }

  const deleteTweets = async () => {
    return Promise.all(tweets.map((tweet) => deleteTweet(tweet)))
  }

  const deleteUsers = async () => {
    return Promise.all(users.map((user) => deleteUser(user)))
  }

  deleteTweets().then(() => {
    deleteUsers()
  })
}

从技术上讲,这可以更容易地概括为

export const clearData = async (prisma) => {
  await prisma.tweet.deleteMany({})
  await prisma.user.deleteMany({})
}

但上面的代码也是有效的,并且展示了如何在Array.map() ,这也是本教程的重点。