狀態機模式 與 ajax 的結合運用

太神奇了,昨晚做了個夢,夢中我悟出一個道理:凡是涉及到異步操作而且需要返回值的函數,一定要封裝成 Promise 的形式,假如返回值取決於多個異步操作的結果,那麼需要對每個異步操作進行狀態的設計,而且需要封裝一個 next 函數。,到了晚上才覺到很有意思,所以結合 ajax 設置最短返回時間和最大返回時間進行實踐:

  const PENDING = 'PENDING'
  const RESOLVED = 'RESOLVED'
  const REJECTED = 'REJECTED'
  const FULLFILLED = 'FULLFILLED'

  /**
   * @desc 異步操作模擬
   * @param time 響應時間
   * @param isError 是否拋錯
   */
  const mock = (time, isError) => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (!isError) {
          resolve({ user: 'ManbaX' })
        } else {
          reject('request error')
        }
      }, time)
    })
  }

  /**
   * @desc 生產不同類型請求的工廠函數
   * @param time 響應時間
   * @param isError 是否拋錯
   */
  var RequestFactory = function (time, isError) {
    var request = function () {
      return new Promise((resolve, reject) => {
        var min = PENDING
        var max = PENDING
        var state = PENDING
        var res = null

        var next = function (name) {
          const cb = function () {
            if (state === RESOLVED) {
              resolve(res)
            } else {
              reject(res)
            }
          }
          if (name === 'res' && min === FULLFILLED) {
            cb()
          }

          if (name === 'min' && (state === RESOLVED || state === REJECTED)) {
            cb()
          }

          if (name === 'max' && state === PENDING) {
            reject('timeout')
          }
        }

        setTimeout(() => {
          min = FULLFILLED
          next('min')
        }, 500)

        setTimeout(() => {
          max = FULLFILLED
          next('max')
        }, 1000)

        mock(time, isError).then(data => {
          res = data
          state = RESOLVED
          next('res')
        }).catch(error => {
          res = error
          state = REJECTED
          next('res')
        })
      })
    }

    return request
  }

  // 不超時, 不返回錯誤
  console.time('r1')
  RequestFactory(200)().then(res => {
    console.log('data: ', res)
  }).finally(() => {
    console.timeEnd('r1')
  })
  
  // 不超時, 返回錯誤
  console.time('r2')
  RequestFactory(200, true)().catch(err => {
    console.log('error', err)
  }).finally(() => {
    console.timeEnd('r2')
  })

  // 超時
  console.time('r3')
  RequestFactory(2000)().catch(res => {
    console.log('error: ', res)
  }).finally(() => {
    console.timeEnd('r3')
  })

上面的運行結果符合預期,本來夢中還有另外一個有意思的東西,但是太模糊了就搞忘記了,下次一定早點記錄。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

您可能也會喜歡…