我有一組list,包含了全部的預約id,如今我須要循環這組id去請求一個接口,以獲取詳情信息.
這裏須要注意的點是:我須要的信息並非一個接口能夠請求完的,而是須要循環請求接口ios
那麼,我如何確保這些接口所有請求完了才執行下面的操做呢?axios
list.map(item => { axios.get(url).then(data => { this.$set(item,"list",data.data.data) }); }); list.map((item)=>{ console.log(item.list) // undefined })
咱們能夠發現,若是不進行任何包裝,僅僅是這樣一個上下結構的邏輯,咱們輸出新插入的值時,發現所有都是undefined,由於請求是異步的.segmentfault
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是異步請求並行操做
咱們能夠經過下面的代碼證明一下promise
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
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一個Promisethis
async getlistdetail(item) { await axios.get(url) .then(data => { this.$set(item, "roundlist", data.data.data); return data.data.data; }); },
最佳解決方法url
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 //後續操做 }