前端專案中如何保證請求時序

Ming_Up發表於2022-06-20

前端專案中經常遇到請求輸入查詢場景,防抖與截流很好處理了頻繁輸入問題,但是不能解決最先發起請求結果後返回,覆蓋了最後一次的搜尋結果,導致搜尋結果不正確。我總結一下自己常用的兩種方法。

  1. 使用時間戳來過濾返回結果,如果請求回撥函式中的時間戳小於當前時間戳則返回,說明已經處理了之後的請求結果了,這個請求過時了。
// 遠端搜尋商品
    searchGoods(data) {
      if (!data) {
        return
      }
      if (this.isRemote) {
        const reqCount = new Date().getTime()
        this.OrderInquireQuerySpuAndUnit({ keyWord: data }).then(res => {
          if (reqCount < this.currentReqCount) {
           return
          }
          if (res.data) {
            if (res.data.length > 0) {
              this.goodsList = res.data
            }
          }
        }).catch(err => {
          console.log(err)
        }).finally(() => {
          this.currentReqCount = reqCount
        })
      }
    },

  1. 基於axios封裝統一的請求方法,後面發起的請求會取消之前等待返回結果的請求,需要多傳一個cancelTokenPath,表示當前同一個輸入元件發起的請求
export const getRequest = param => {
  const { cancelTokenPath, ...restQuery } = (param && param.query) || {}
    // cancelTokenPath是為了避免頁面中多處請求的同一個接,導致錯誤的取消
  if (cancelTokenPath) {
    const CancelToken = axios.CancelToken
    const source = CancelToken.source()

    if (store[cancelTokenPath]) {
      store[cancelTokenPath].cancel('Canceled by the last request')
    }
    store[cancelTokenPath] = source
  }

  return new Promise((resolve, reject) => {
    Vue.axios
      .get(param.url, {
        params: restQuery || {},
        headers: param.headers || {},
        cancelToken: cancelTokenPath && store[cancelTokenPath].token
      })
      .then(res => { resolve(res) })
      .catch(err => {
        reject(err)
      })
  })
}

相關文章