国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

react-native fetch的具體使用方法

2019-11-19 15:00:59
字體:
來源:轉載
供稿:網友

在前端快速發展地過程中,為了契合更好的設計模式,產生了 fetch 框架,此文將簡要介紹下 fetch 的基本使用。

在 AJAX 時代,進行請求 API 等網絡請求都是通過 XMLHttpRequest 或者封裝后的框架進行網絡請求。

現在產生的 fetch 框架簡直就是為了提供更加強大、高效的網絡請求而生,雖然在目前會有一點瀏覽器兼容的問題,但是當我們進行 Hybrid App 開發的時候,如我之前介紹的Ionic 和React Native,都可以使用 fetch 進行完美的網絡請求。

fetch 初體驗

在 Chrome 瀏覽器中已經全局支持了 fetch 函數,打開調試工具,在 Console 中可以進行初體驗。先不考慮跨域請求的使用方法,我們先請求同域的資源,如在我的博客頁面中,打開 Console 進行如下請求。

fetch("http://blog.parryqiu.com").then(function(response){console.log(response)})

返回的數據:

這樣就很快速地完成了一次網絡請求,我們發現返回的數據也比之前的 XMLHttpRequest 豐富、易用的多。

關于 fetch 標準概覽

雖然 fetch 還不是作為一個穩定的標準發布,但是在其一直迭代更新的 標準描述 中,我們發現已經包含了很多的好東西。

fetch 支持了大部分常用的 HTTP 的請求以及和 HTTP 標準的兼容,如 HTTP Method,HTTP Headers,Request,Response。

fetch 的使用

fetch的入口函數定義在node_modules/whatwg-fetch.js文件中,如下

 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 failed888888888888'))   }   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)   })   xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)  }) }

該函數在Network/fetch.js中被導出,最終在initializeCore.js中被注冊為global的屬性變為全局函數。fetch返回的是一個Promise。

跟隨方法走向,依次調用的是XMLHttpRequest.js的send -> RCTNetworking.ios.js的sendRequest -> 最終調到原生端RCTNetworking.mm的sendRequest方法。

相關問題點:

1、為何fetch函數無法設置timeout?

為了設置fetch的timeout,我會如下定義一個函數

 _timeout_fetch(fetch_promise, timeout = 15000) {  let timeout_promise = new Promise(function (resolve, reject) {   setTimeout(() => {    reject('timeout promise');   }, timeout)  });  return Promise.race([   fetch_promise,   timeout_promise  ]); }

然后如下調用

 this._timeout_fetch(    fetch(url, requestParams)     .then(response => response.json())     .then(responseData => {      resolve(responseData);     })     .catch(error => {      reject(error);     })   )

先定義一個Promise,其在超時時間結束后reject。將這個Promise和fetch合并到Promise.race中,則一旦這兩個請求誰先執行,另外一個會被舍棄。這樣完成超時時間的設置。

但是查看源碼發現oc中是有超時時間設置這個選項的,且js和oc通信時也傳了這個參數,問題是出在入口函數fetch處,只需要在上面fetch方法中添加上如下

 xhr.timeout = init.timeout || 0;

就可以在請求參數中設置超時時間了,如

 let requestParams = {   method: method,   header: {    "Content-Type": "application/json;charset=UTF-8",   },   timeout: 1000  };

2、fetch函數為何無法cancel?

fetch在原生端是NSURLSessionDataTask發的請求,這個是可取消的。在js端的XMLHttpRequest.js中也發現了abort方法,調用能夠取消當前網絡請求。問題出在了fetch的接口函數。

首先,要想請求能夠取消,得拿到當前請求對應的requestId。請求的執行順序是js端發起 -> OC生成Request,得到requestId,利用NSURLSessionDataTask發起請求 -> 將requestId通過回調的形式傳回給js端,js若想取消該請求,執行abort方法即可。

要想fetch函數能夠執行cancel,只需該方法將XMLHttpRequest對象返回即可。但是那樣,就不再是一個Promise了。
也可以將cancel方法綁定到返回的Promise對象上,修改方法如下

 self.fetch = function (input, init) {  var xhr = new XMLHttpRequest()  let p = new Promise(function (resolve, reject) {   var request = new Request(input, init)   // xhr的各種設置,回調等  })  p.cancel = () => {   xhr.abort()  }  return p; }

如此,調用的時候就比較惡習了,要如下

  let promise = fetch(url);  promise.then(res => {  }).then(res => {  }).catch(err => {  })  promise.cancel() // 取消該網絡請求

不能fecth().then().then()的模式調用,因為這樣會導致返回的那個Promise不再是上面綁定了cancel的那個Promise。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 图片| 新巴尔虎左旗| 玛曲县| 浮梁县| 阿瓦提县| 岳阳市| 安阳县| 安塞县| 华池县| 工布江达县| 瓦房店市| 台中市| 瑞安市| 易门县| 新巴尔虎左旗| 东乡族自治县| 丰县| 吉木萨尔县| 威海市| 井冈山市| 郴州市| 扬州市| 新野县| 平陆县| 曲靖市| 桃源县| 巴彦淖尔市| 浮梁县| 青神县| 平泉县| 资溪县| 通许县| 白朗县| 乡宁县| 潜山县| 辽阳市| 横山县| 岳阳市| 乃东县| 洪泽县| 蓝田县|