[vue.js]關於使用Promise/async await解決循環請求接口的問題

問題背景:

我有一組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

解決方法:

使用Promise解決
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")

image.png
咱們能夠發現整個程序用了1s就運行完了,而非3s異步

若是你在使用Promise.all時出現瞭如下報錯:
cannot read property Symbol(Symbol.iterator)
那麼請注意Promise.all的正確寫法是:
Promise.all([promise1,promise2,promise3])
而不是:Promise.all(promise1,promise2,promise3)async

使用async/await結合Promise (串行)
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;
        });
    },
使用async/await結合Promise (並行)

最佳解決方法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
      //後續操做
}
相關文章
相關標籤/搜索