fetch函數設置timeout

使用react-native開發app時,通常使用fetch函數與後臺進行交互。請求後臺接口時,爲了防止用戶等待太長時間需要設置timeout,但是原生的fetch並沒有設置timeout的地方。本文介紹一種設置timeout的方法。

一、修改fetch源代碼

     self.fetch = function(input, init) {
    return new Promise(function(resolve, reject) {
      var request = new Request(input, init)
      var xhr = new XMLHttpRequest()

      xhr.onload = function() {
        var options = {
          status: xhr.status,
          statusText: xhr.statusText,
          headers: parseHeaders(xhr.getAllResponseHeaders() || '')
        }
        options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
        var body = 'response' in xhr ? xhr.response : xhr.responseText
        resolve(new Response(body, options))
      }

      xhr.onerror = function() {
        reject(new TypeError('Network request failed'))
      }

      xhr.ontimeout = function() {
        reject(new TypeError('Network request failed'))
      }

      xhr.open(request.method, request.url, true)

      if (request.credentials === 'include') {
        xhr.withCredentials = true
      }

      if ('responseType' in xhr && support.blob) {
        xhr.responseType = 'blob'
      }

      request.headers.forEach(function(value, name) {
        xhr.setRequestHeader(name, value)
      })
      //設置fetch函數請求的超時時間
      if(init!=null&&init.timeout!=null){
        xhr.timeout=init.timeout;
      }
      xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
    })
  }

觀察代碼能夠發現,fetch函數將input與init兩個參數封裝成一個Request類並通過XMLHttpReauest類的send方法發送請求。其中input爲接口的url地址,init爲fetch函數的設置對象,包括method、headers等屬性。

RCTNetworking.sendRequest(
      this._method,
      this._trackingName,
      this._url,
      this._headers,
      data,
      nativeResponseType,
      incrementalEvents,
      this.timeout,
      this.__didCreateRequest.bind(this),
      this.withCredentials
    );

繼續觀察XMLHttpReauest的代碼發現,XMLHttpReauest進一步通過原生類RCTNetworking的sendRequest方法發送請求,其中this.timeout中this爲XMLHttpReauest的實例對象xhr。因此,可以通過爲xhr設置timeout達到爲fetch函數設置timeout的目的,只需要在fetch函數中添加以下代碼:

//設置fetch函數請求的超時時間
      if(init!=null&&init.timeout!=null){
        xhr.timeout=init.timeout;
      }

現在,你可以在fetch函數中設置設置timeout值了。

return fetch(constant.SERVICE_URL + srvName, {
        method: 'POST',
        credentials: 'include',   //credentials默認omit,即不傳cookie
        mode: 'cors',
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: args,
        timeout: constant.TIMEOUT
    })
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章