如何使Promise.all返回的结果按顺序排列

3
问题: case1的输出是按顺序从0到4,而case2的输出是随机的。
我知道case1结果按顺序排列的原因是请求是在前一个请求的结果之后发送的。 在case2中,请求不会等待前一个请求的结果。
我的问题是,是否有一种方法也能使case2的结果按顺序排列?
case1
const main = async () => {
    const arr = Array.of(...[1,2,3,4,5])

    for (let i=0;i<arr.length;i++) {
        console.log(`request:${i}`)
        const res = await request(i)
        console.log(res)
    }


    console.log("next step")

}

const request = (i:number):Promise<number> => {
    return new Promise<number>(((resolve, reject) => {
        setTimeout(()=>{
            resolve(i)
        },Math.random() * 1000)
    }))
}

输出1

closure
request:0
0
request:1
1
request:2
2
request:3
3
request:4
4
next step

案例2

const main = async () => {
    const arr = Array.of(...[1,2,3,4,5])
    await Promise.all(arr.map(async (v,i) => {
        console.log(`request:${v}`)
        const res = await request(v)
        console.log(`result:${res}`)
        console.log(res)
    })).catch((e) => {

    })


    console.log("next step")

}

const request = (i:number):Promise<number> => {
    return new Promise<number>(((resolve, reject) => {
        setTimeout(()=>{
            resolve(i)
        },Math.random() * 1000)
    }))
}

main()

输出2

request:1
request:2
request:3
request:4
request:5
result:4
4
result:5
5
result:1
1
result:3
3
result:2
2
next step


没有合理的方法可以在完全不删除Promise.all的情况下实现,我认为。 - CertainPerformance
2个回答

5

Promise.all() 方法返回一个数组,保存着相同顺序的结果; 但是它们不会按顺序解析。您可以在 request promise 中返回响应并...

const [result1, result2, result3] = await Promise.all([promise1, promise2, promise3]);

或者,如果您想要迭代一个数组...

const results = await Promise.all([promise1, promise2, promise3]);

嗨,Ben Chamberlin 结果以这种方式保持顺序,并且请求按顺序发送 我们能否仅在前一个请求的响应后才发送每个请求? 就像 请求0 响应0 请求1 响应1 请求2 响应2 ..... 请求n 响应N - Zhongwei Xu
1
如果你想在前一个 Promise 解决后只运行下一个 Promise,那么你需要单独等待每个 Promise。Promise.all() 只应在你想同时运行它们时使用。 - Ben Chamberlin

2

Promise All should be array of request or promise, in map() should return request. try this

const main =  () => {
    const arr = Array.of(...[1,2,3,4,5])
     Promise.all(arr.map((v,i) => {
        console.log(`request:${v}`)
         return  request(v)   
    })).then((res)=>{
    res.forEach((val)=>{
        console.log(`result:${val}`)
    })
       
    }).catch((e) => {

    })
    console.log("next step")

}

 const request = (i)=> {
     return new Promise((resolve, reject) => {
        setTimeout(()=>{
            resolve(i)
        }, Math.floor(Math.random() * 10)*1000)
    })
} 

main()


嘿,ranganathan Promise All 可以让请求在前一个请求的响应后才发送吗? 就像这样请求0 响应0 请求1 响应1 请求2 响应2 ..... 请求n 响应N - Zhongwei Xu
嗨,我认为使用 Promise.all 无法实现,请尝试使用 async 和 await。 - ranganathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接