前言
遇到这样一个需求:调用接口,返回一个新闻列表,再循环这个新闻列表,用每个新闻的id异步请求这个新闻的视频地址,这就需要在循环里调用接口。如果用for循环,接口还没请求完成,for循环就已经执行完了。所以改成promise去处理。
开始
整体思路就是:先存数组,然后循环生成每一个promise,然后用promise.all来调用,then的时候返回的是一个结果数组。
1、首先定义循环里的异步请求
getInfo(item ,index){
return new Promise((resolve,reject) => {
axios.post('/videoUrl',{id:item.id}).then(res=>{
let url = res.data;
resolve({id:item.id,url:url})
})
})
}
2、newsList为开始接口获取的新闻列表,对新闻列表进行循环,得到一个promise数组。
let promiseArr = this.newsList.map((item,index) => {
return this.getInfo(item, index)
})
3、用promise.all来调。
Promise.all(promiseArr).then(value=>{
console.log(value);
//value:[{id: 1, url: "xxxxx"},
// {id: 2, url: "xxxxx"},
// {id: 3, url: "xxxxx"}]
this.newsList = value;
})
这样就拿到了包含新闻视频地址的新闻列表。
全部代码
<script>
export default {
name: 'empty',
data () {
return {
newsList:[]//新闻列表
}
},
methods:{
getNewsList(){
axios.get('/newsList').then(res=>{
this.newsList = res.data;//newsList = [{id:1},{id:2},{id:3}];
let promiseArr = this.newsList.map((item,index) => {
return this.getInfo(item, index)
})
Promise.all(promiseArr).then(value=>{
console.log(value);
//value:[{id: 1, url: "xxxxx"},
// {id: 2, url: "xxxxx"},
// {id: 3, url: "xxxxx"}]
this.newsList = value;
})
})
},
// 通过新闻id请求新闻视频地址
getInfo(item ,index){
return new Promise((resolve,reject) => {
axios.post('/videoUrl',{id:item.id}).then(res=>{
let url = res.data;
resolve({id:item.id,url:url})
})
})
}
},
mounted(){
this.getNewsList();
}
}
</script>
后记
1、首先关于后台修改接口,正常返回应该是newsList里就返回了视频地址,协商过就是需要单独去调用。
2、这个问题的解决花费了时间,特此记录。文章参考javascript for循环+异步请求导致请求顺序不一致