Call the asynchronous interface in the loop to get data

foreword

Encountered such a requirement: call the interface, return a news list, recycle the news list, and use the id of each news to asynchronously request the video address of the news, which requires calling the interface in the loop. If you use a for loop, the for loop has already been executed before the interface request is completed. So change it to promise to handle it.

start

The overall idea is: store the array first, then generate each promise in a loop, and then call it with promise.all, and then return an array of results.

1. First define the asynchronous request in the loop

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 is the news list acquired by the start interface, and the news list is looped to obtain a promise array.

let promiseArr = this.newsList.map((item,index) => {
    
    
				    return this.getInfo(item, index)
				 })

3. Use promise.all to adjust.

Promise.all(promiseArr).then(value=>{
    
    
						console.log(value);
					 //value:[{id: 1, url: "xxxxx"},
					// 		  {id: 2, url: "xxxxx"},
					// 		  {id: 3, url: "xxxxx"}]
						this.newsList = value;
					})

In this way, the news list including the address of the news video is obtained.

all codes

<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>

postscript

1. First of all, regarding the background modification interface, the normal return should be that the video address is returned in the newsList, and it needs to be called separately after negotiation.
2. It took time to solve this problem, which is hereby recorded. Article reference javascript for loop + asynchronous request leads to inconsistent request order

Guess you like

Origin blog.csdn.net/qq_39352780/article/details/107400913