Promise/async await解决循环请求接口的问题

问题背景:

我有一组list,包含了所有的预定id,现在我需要循环这组id去请求一个接口,以获取详情信息.

这里需要注意的点是:我需要的信息并不是一个接口可以请求完的,而是需要循环请求接口

那么,我如何确保这些接口全部请求完了才执行下面的操作呢?

list.map(item => {

axios.get(url).then(data => {

this.$set(item,"list",data.data.data)

});

});

list.map((item)=>{

console.log(item.list) // undefined

})

我们可以发现,如果不进行任何包装,仅仅是这样一个上下结构的逻辑,我们输出新插入的值时,发现全部都是undefined,因为请求是异步的.

解决方法:

使用Promise解决

let queue = list.map(item => {

return new Promise(resolve => {

axios.get(url).then(data => {

resolve(data.data.data);

});

});

});

Promise.all(queue).then(result => {

//TODO

//执行后续操作

});

Promise.all 方法会等待所有的 异步任务执行结束了,然后将所有任务的执行结果都统一的放到一个数组中,然后传给自己的 then

另外,Promise.all是异步请求并行操作

我们可以通过下面的代码证实一下

console.time("test")

var list = [1,2,3]

var queue =list.map((item)=>{

return new Promise((resolve,rejcet)=>{

setTimeout(() => {

resolve(item)

}, 1000);

})

})

Promise.all(queue).then((res)=>{

console.log(res)

})

console.timeEnd("test")

我们可以发现整个程序用了1s就运行完了,而非3s

如果你在使用Promise.all时出现了以下报错:

cannot read property Symbol(Symbol.iterator)

那么请注意Promise.all的正确写法是:

Promise.all([promise1,promise2,promise3])

而不是:Promise.all(promise1,promise2,promise3)

使用async/await结合Promise (串行)

async getlist() {

for (const item of list) {

const column = await getlistdetail(item)

}

//TODO

//后续操作

},

getlistdetail(item) {

return new Promise(resolve => {

axios

.get(url).then(data => {

this.$set(item, "roundlist", data.data.data);

resolve(data.data.data);

});

});

}

由于异步等待axios返回的本身就是一个Promise对象,所以重新再封装一层的必要性不大,可以直接return一个Promise

 async getlistdetail(item) {

await axios.get(url)

.then(data => {

this.$set(item, "roundlist", data.data.data);

return data.data.data;

});

},

使用async/await结合Promise (并行)

最佳解决方法

async getlist() {

let list = await this.getlist();//获取id合集

const promises = list.map(x => this.getlistdetail(x));//根据每个id分别请求接口获取详情

for (const promise of promises) {

const column = await promise;

}

//TODO

//后续操作

}

以上是 Promise/async await解决循环请求接口的问题 的全部内容, 来源链接: utcz.com/a/14549.html

回到顶部