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
    })
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章