每一門語言都離不開網絡請求,有本身的一套Networking Api。React Native使用的是Fetch。 今天咱們來談談與Fetch相關的一些事情。java
經過這篇文章,你將瞭解到如下幾點關於Fetch的獨家報道react
fetch的使用很是簡單,只需傳入請求的urlgit
fetch('https://facebook.github.io/react-native/movies.json');
固然是否請求成功與數據的處理,咱們還需處理成功與失敗的回調github
function getMoviesFromApiAsync() { return fetch('https://facebook.github.io/react-native/movies.json') .then((response) => response.json()) .then((responseJson) => { return responseJson.movies; }) .catch((error) => { console.error(error); }); }
經過response.json()將請求的返回數據轉化成json數據以便使用。經過.then
來對數據進行轉化處理或最終暴露給調用者;.catch
對異常的處理。web
以上就是一個簡單的網絡請求,該請求默認是get方式。那麼post又該如何請求呢?算法
在fetch中咱們直接傳入url進行請求,其實內部本質是使用了Request對象,只是將url出入到了Request對象中。json
const myRequest = new Request('https://facebook.github.io/react-native/movies.json'); const myURL = myRequest.url; // https://facebook.github.io/react-native/movies.jsonflowers.jpg const myMethod = myRequest.method; // GET fetch(myRequest) .then(response => response.json()) .then(responseJson => { //todo });
若是咱們須要請求post,須要改變Request的method屬性。segmentfault
fetch('https://mywebsite.com/endpoint/', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ firstParam: 'yourValue', secondParam: 'yourOtherValue', }), });
很是簡單,在url後直接傳入{}對象,其中指定method使用post。react-native
相信你們應該都知道get與post的一個主要區別是get能夠在url上直接添加參數,而post爲了安全都不採用直接將參數追加到url上,而是使用body來傳給service端。緩存
在使用body前,這裏還需知道headers。下面某個post請求的headers信息
須要注意的是Content-Type字段,它表明的是service端接收的數據類型,圖片中使用的是application/x-www-form-urlencoded。這對於咱們的body來講是很是重要的。只有匹配Content-Type的類型才能正確的傳遞參數信息。
示例的代碼使用的是application/json,因此body使用Json.stringify()進行參數轉換,而對於Content-Type爲application/x-www-form-urlencoded,須要使用queryString.stringify()。
Request中除了method、headers與body,還有如下屬性
請求成功以後,使用.then來轉換數據,使用最多的是Body.json(),固然你也可使用如下的幾種數據轉換類型
以上是fetch請求相關的屬性與方法。若是你已經有所瞭解,那麼恭喜你對fetch的基本使用已通過關了,下面對fetch的使用進行封裝。
在實際開發中,url的host都是相同的,不一樣的是請求的方法名與參數。而對於不一樣的環境(debug|release)請求的方式也可能不一樣。例如:在debug環境中爲了方便調試查看請求的參數是否正確,咱們會使用get來進行請求。因此在封裝以前要明確什麼是不變的,什麼是變化的,成功與失敗的響應處理。
通過上面的分析,羅列一下封裝須要作的事情。
function convertUrl(url, params) { let realUrl = ApiModule.isDebug? url + "?" + queryString.stringify(Object.assign({}, params, commonParams)) : url; if (ApiModule.isDebug) { console.log("request: " + realUrl); } return realUrl; }
首先對url與參數params進行拼接,若是爲debug模式將params拼接到url後。這裏使用到了Object.assign()將params與commonParams組合成一個{}對象。最終經過queryString.stringify轉化成string。
ApiModule.isDebug是原生傳遞過來的值,對於Android/IOS只需傳遞本身的ApiModule便可。
function getMethod() { return ApiModule.isDebug? "get": "post"; }
上述提到的get與post的請求時機。
const headers = { Accept: 'application/json', "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" };
在headers中Content-Type類型爲application/x-www-form-urlencode
function convertBody(params) { return ApiModule.isDebug? undefined : queryString.stringify(Object.assign({}, params, commonParams)); }
因爲debug模式使用的是get方式,但get規定是不能有body的,因此這裏使用了undefined來標識。同時爲了匹配headers中的Content-Type,params的轉化必須使用queryString.stringify;若是接受的是json,可使用JSON.stringify。
定義完以後fetch對外只需接受params參數便可。
async function fetchRequest(params){ let body = convertBody(params); fetch(convertUrl(baseUrl, params),{ method: method, headers: headers, body: body }) .then((response) => response.json()) .then((responseJson) => { //todo success }) .catch((error) => { if (ApiModule.isDebug) { console.error("request error: " + error); }; //todo error }); }
fetch的請求封裝完成,但咱們的成功與失敗的狀態並無通知給調用者,因此還須要一個回調機制。Promise是一個異步操做最終完成或者失敗的對象。它能夠接受兩個函數resolve、reject
const p = new Promise((resolve, reject){ ... //success resolve('success') //error reject('error') }); //use p.then(success => { console.log(success); }, error => { console.log(error) });
將fetch請求放入到Promise的異步操做中,這樣一旦數據成功返回就調用resolve函數回調給調用者;失敗調用reject函數,返回失敗信息。而調用者只需使用Promise的.then方法等候數據的回調通知。下面來看下完整的fetch封裝。
async function fetchRequest(params){ let body = convertBody(params); return new Promise(function(resolve, reject){ fetch(convertUrl(baseUrl, params),{ method: method, headers: headers, body: body }) .then((response) => response.json()) .then((responseJson) => { resolve(responseJson); }) .catch((error) => { if (ApiModule.isDebug) { console.error("request error: " + error); }; reject(error); }); }); }
以後對fetch的使用就很是簡單了,只需傳入須要的參數便可。
fetchRequest({method: "goods.getInfo", goodsId: 27021599158370074}) .then(res =>{ this.setState({ shareInfo: res.data.shareInfo }); });
以上是有關fetch的所有內容,固然在React Native中還有其它的第三方請求庫:XMLHttpRequest,同時也支持WebSockets。感興趣的也能夠去了解一下,相信會有不錯的收穫。
拉粉環節:感受不錯的能夠來一波關注,掃描下方二維碼,關注公衆號,及時獲取最新知識技巧。