首页 > 解决方案 > 如何使用 Promise.All() 执行异步承诺?

问题描述

我想问一下,你是如何在promise all中运行ascyronus promises的?当我运行我创建的函数时 Promise.all 并行运行所有函数(同步)

如果您运行下面的代码,那么结果是

// jon
// andrey
// tania
// JON
// ANDREY
// TANIA

这是我的代码

// First promise returns an array
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve([{ id: 'jon' }, { id: 'andrey' }, { id: 'tania' }]), 600)
  })
}

// Second promise relies on the resulting array of first promise
const getIdFromUser = users => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(users.id), 500)
  })
}

// Third promise relies on the result of the second promise
const capitalizeIds = id => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 200)
  })
}

const newPromise = async user => {
      const userId = await getIdFromUser(user)
      console.log(userId) //jon
      const capitalizedId = await capitalizeIds(userId)
      console.log(capitalizedId) //JON
      return
  }

const runAsyncFunctions = async () => {
  const users = await getUsers()
  
  await  Promise.all(users.map(user => newPromise(user)))
}

runAsyncFunctions()

但我想要如下结果,如果承诺全部运行异步,这将起作用

// jon
// JON
// andrey
// ANDREY
// tania
// TANIA

这是我的操场代码操场

标签: javascriptnode.js

解决方案


如果您只想在最后一个 Promise 完成后才初始化 Promise - 也就是说,以串行方式而不是并行方式运行它们 - 那么.map并且Promise.all不是该工作的正确工具,因为这将立即初始化所有 Promise。await而是在一个for循环中:

const runAsyncFunctions = async() => {
  const users = await getUsers()
  for (const user of users) {
    await newPromise(user);
  }
}

// First promise returns an array
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve([{
      id: 'jon'
    }, {
      id: 'andrey'
    }, {
      id: 'tania'
    }]), 600)
  })
}

// Second promise relies on the resulting array of first promise
const getIdFromUser = users => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(users.id), 500)
  })
}

// Third promise relies on the result of the second promise
const capitalizeIds = id => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 200)
  })
}

const newPromise = async user => {
  const userId = await getIdFromUser(user)
  console.log(userId) //jon
  const capitalizedId = await capitalizeIds(userId)
  console.log(capitalizedId) //JON
  return
}

const runAsyncFunctions = async() => {
  const users = await getUsers()
  for (const user of users) {
    await newPromise(user);
  }
}

runAsyncFunctions()

如果您的真实代码允许您在外部进行日志记录,您可以继续并行运行 Promises,但只有在它们全部完成后才按顺序记录结果:

const newPromise = async user => {
  const userId = await getIdFromUser(user)
  const capitalizedId = await capitalizeIds(userId)
  return [userId, capitalizedId];
}
const runAsyncFunctions = async() => {
  const users = await getUsers()

  const names = await Promise.all(users.map(user => newPromise(user)));
  for (const name of names.flat()) {
    console.log(name);
  }
}

// First promise returns an array
const getUsers = () => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve([{
      id: 'jon'
    }, {
      id: 'andrey'
    }, {
      id: 'tania'
    }]), 600)
  })
}

// Second promise relies on the resulting array of first promise
const getIdFromUser = users => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(users.id), 500)
  })
}

// Third promise relies on the result of the second promise
const capitalizeIds = id => {
  return new Promise((resolve, reject) => {
    return setTimeout(() => resolve(id.toUpperCase()), 200)
  })
}

const newPromise = async user => {
  const userId = await getIdFromUser(user)
  const capitalizedId = await capitalizeIds(userId)
  return [userId, capitalizedId];
}

const runAsyncFunctions = async() => {
  const users = await getUsers()

  const names = await Promise.all(users.map(user => newPromise(user)));
  for (const name of names.flat()) {
    console.log(name);
  }
}

runAsyncFunctions()


推荐阅读