for迴圈中介面呼叫
阿新 • • 發佈:2021-06-30
起因:同事發現一個外層陣列為0,但長度為2,這種“奇怪”的資料結構
正確的資料結構
原因:迴圈中執行非同步請求導致的
復現業務程式碼:
//模擬ajax請求
function ajax(){ let data = [{name:'小明',age:22},{name:'小紅',age:18}] return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(data) },200) }) } //因業務要求,迴圈中呼叫介面 function run(){ let userList= [{id:1},{id:2}]; let list = []; userList.forEach((item)=>{ ajax().then((res)=>{ list.push(res) }) }) console.log(list) } run()
解決方式一 :Promise.all
function ajax() { let data = [{ name: '小明', age: 22 }, { name: '小紅', age: 18 }] returnnew Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 200) }) } 建立Promise方法 function createPromise() { let promise = new Promise((resolve, reject) => {
//將業務介面的返回值,resolve進去 ajax().then((res) => { resolve(res) }) })return promise } function run() { let userList = [{ id: 1 }, { id: 2 }]; let list = []; let resList = []; userList.forEach((item) => { list.push(createPromise()) }) Promise.all(list).then((res) => { resList = res }) } run()
缺點:
1.Promise.all得等所有請求成功,才能返回,會遇到阻塞問題
2.Promise.all得等所有請求響應,響應時間太長問題
解決方式二 :遞迴呼叫介面
function ajax() { let data = [{ name: '小明', age: 22 }, { name: '小紅', age: 18 }] return new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 200) }) }
遞迴終止條件,陣列長度小於 async function run(length, arr) { const res = await ajax(); arr.push(res) if (length> 1) { await run(length- 1, arr) } return arr } async function getResult() { let userList = [{ id: 1 }, { id: 2 }]; let res = await run(userList.length, []); } getResult()