【问题标题】:How to join a chain of promises into a single promise如何将一连串的 promise 加入到一个 promise 中
【发布时间】:2022-11-22 11:47:16
【问题描述】:

我想将一连串的 Promise 返回到一个 Promise 中。我想知道如何实现它。

function xbox(){
    let games = "https://api.rawg.io/api/games?key=f648fbbe7d024a9d9b021bbd24cea8b5"
    let pages = []
    let videogames = []
    let play
    for(let i = 1; i <= 5; i++){
        let response = fetch(games + `&page=${i}`)
        pages.push(response)
        let game = response.then(res => res.json()).then(data => data.results.map((e) => {
            let allgames = {
                ID: e.id
            }
            return allgames
        }))
        videogames = videogames.concat(game)
        play = Promise.all(videogames.flat(1))
    }
    return play
}

输出

基本上我想要的输出是一个单一的 Promise,而不是显示一个包含 5 个 Promise 和 20 个结果的链,一个单一的 Promise 有 100 个结果。

我感谢任何帮助我的查询!

【问题讨论】:

  • 你有没有使用async/await的原因?
  • 我在 Chrome 的开发者工具中使用控制台登录。只是出于好奇:)

标签: javascript arrays promise fetch-api


【解决方案1】:

展平结果在承诺数组上调用Promise.all

return play
  .then(results => results.flat());

function xbox(){
    let games = "https://api.rawg.io/api/games?key=f648fbbe7d024a9d9b021bbd24cea8b5"
    let pages = []
    let videogames = []
    let play
    for(let i = 1; i <= 5; i++){
        let response = fetch(games + `&page=${i}`)
        pages.push(response)
        let game = response.then(res => res.json()).then(data => data.results.map((e) => {
            let allgames = {
                ID: e.id
            }
            return allgames
        }))
        videogames = videogames.concat(game)
        play = Promise.all(videogames.flat(1))
    }
    return play
      .then(results => results.flat());
}
xbox().then(console.log);

进一步清理你的代码,它可以看起来像:

function xbox(){
    const baseUrl = "https://api.rawg.io/api/games?key=f648fbbe7d024a9d9b021bbd24cea8b5";
    return Promise.all(Array.from(
        { length: 5 },
        (_, i) => fetch(baseUrl + '&page=' + (i + 1))
          .then(res => res.json())
          .then(data => data.results.map(({ id }) => ({ ID: id })))
    ))
      .then(results => results.flat());
}
xbox().then(console.log);

【讨论】:

    【解决方案2】:

    您可以简单地使用 promise all 并将所有 promise 组合成一个。

    您的代码的问题是您正在尝试循环,并且在每次迭代中您都试图将承诺作为 Promise.all,这没有意义,因为在每次迭代中您只获得一个承诺。

    所以你需要循环并收集所有的承诺,然后把它放在 Promise.all

    function xbox() {
      let games = "https://api.rawg.io/api/games?key=f648fbbe7d024a9d9b021bbd24cea8b5"
      return Promise.all(Array.from({
        length: 5
      }, (a, i) => i + 1).map(v => {
        return fetch(games + `&page=${v}`).then(res => res.json()).then(data => data.results.map((e) => {
          let allgames = {
            ID: e.id
          }
          return allgames
        }))
      }))
    }
    
    xbox().then(d => console.log(d.flat(1)))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-06
      • 2020-12-08
      • 2019-09-17
      • 2016-11-21
      • 1970-01-01
      • 2017-10-11
      • 2017-07-31
      • 2017-01-04
      相关资源
      最近更新 更多