这都是上家公司遇到的问题了,今天阿伟问我给解决了。有个需求是循环请求一个接口获得数据(这按理说是后台该做的,循环请求确实不太符合规范),但确实遇到了,问题是循环请求了但是接口是异步的,你按顺序传过去的返回来的并不一定按顺序返回来,当时我寻思了不少办法,理论可行的是同步请求接口,但因为改动太大没尝试,再有就是await方法,但是因为当时猪油蒙了心试了试不好使,一会儿我会说为啥不好使,到最后定时200毫秒请求一次,虽然也堪堪实现了,但一套下来变得很慢不说,有时候网络或者电脑反应慢还会导致次序错乱。
先贴一张之前尝试的图
因为这么用async导致我一直没成功,也是对async理解不透彻,光想着await去等耗时的请求,忽略了async的异步,导致for循环没有被阻塞,然后我就到处找能阻塞住for循环的办法,但网上都是说怎么教你异步的,很少有说怎么阻塞程序的,最终无果。
然后最终解决来了
mounted() {
this.queryNewFund()
},
methods: {
async queryNewFund() {
let that = this
let codeList = ['1', '2', '3']
for (let i = 0; i < codeList.length; i++) {
let obj = await that.getData(codeList[i]);
console.log(obj)
}
},
getData(code) {
if (code == '1') {
return new Promise((resolve) => {
setTimeout(() => {
resolve('aaa')
}, 2000)
})
}
if (code == '2') {
return new Promise((resolve) => {
setTimeout(() => {
resolve('bbb')
}, 500)
})
}
if (code == '3') {
return new Promise((resolve) => {
setTimeout(() => {
resolve('ccc')
}, 500)
})
}
}
}
复制代码
这样打印顺序是aaa、bbb、ccc解决了业务需求,for循环也被阻塞住了。
好几天没看没想到有这么多留言,本身是为了给自己留个笔记,很多朋友提到了Promise.all,之前确实不知道,然后试了试。
aa() {
let that = this
let codeList = ['1', '2', '3']
let list=[]
for(let i in codeList){
list.push(this.bb(codeList[i]))
}
Promise.all([this.bb(1), this.bb(2), this.bb(3)]).then((values) => {
console.log(values);//['aaa', 'bbb', 'ccc']
});
},
bb(code) {
if (code == '1') {
return new Promise((resolve) => {
setTimeout(() => {
resolve('aaa')
}, 2000)
})
}
if (code == '2') {
return new Promise((resolve) => {
setTimeout(() => {
resolve('bbb')
}, 500)
})
}
if (code == '3') {
return new Promise((resolve) => {
setTimeout(() => {
resolve('ccc')
}, 500)
})
}
复制代码
确实要比await阻塞要好,如上例子await理论要2000+500+500毫秒,但Promise.all取最长的2000就回来了。感谢大伙儿的指导。