React Native has built-in XMLHttpRequest network request API(also known as Ajax). However, XMLHttpRequest is a poorly designed API that does not comply with the principle of separation of responsibilities. The configuration and invocation methods are confusing. And the event-based asynchronous model is not as friendly to write as modern Promise. Fetch was invented to solve XHR problems, so React Native officially recommends using the Fetch API.

The following is an example of the FETCH request:

return fetch('http://facebook.github.io/react-native/movies.json').then((response) => response.json())
    .then((responseJson) => {
      return responseJson.movies;
    })
    .catch((error) => {
      console.error(error);
    });Copy the code

Please refer to the following articles for detailed introduction and usage instructions of the Fetch API:

Use Promise to encapsulate the FETCH request

Since network request is needed in many places in the project, ES6 Promise is used to encapsulate fetch network request for convenience. The code is as follows:

let common_url = 'http://192.168.1.1:8080/';  //Server addresslet token = ' '; / * * *@param{string} URL Interface address *@param{string} method Request methods: GET and POST, uppercase * only@param {JSON} [params=' '] body request parameter, which defaults to empty *@returnReturns the Promise * /function fetchRequest(url, method, params = ' ') {let header = {
        "Content-Type": "application/json; charset=UTF-8"."accesstoken":token  //The token returned by the user after login. Some interfaces involving user data need to add token} in the header.console.log('request url:',url,params);  //Print request parametersif(params == ' ') {//If the network request has parametersreturn new Promise(function (resolve, reject) {
            fetch(common_url + url, {
                method: method,
                headers: header
            }).then((response) => response.json())
                .then((responseData) => {
                    console.log('res:',url,responseData);  //Resolve (responseData); })
                .catch( (err) => {
                    console.log('err:',url, err);     //Reject (ERR) Data returned when a network request fails. });
        });
    }else{// If there are no parameters in the network requestreturn new Promise(function (resolve, reject) {
            fetch(common_url + url, {
                method: method,
                headers: header,
                body:JSON.stringify(params)   //The body argument, which usually needs to be converted to a string before the server can parse it}).then((response) => response.json())
                .then((responseData) => {
                    console.log('res:',url, responseData);   //Resolve (responseData); }).catch( (err) => {
                    console.log('err:',url, err);   //Reject (ERR) Data returned when a network request fails. }); }); }}Copy the code

Produces =”text/ HTML; produces=” produces=”; produces=”; produces=”; charset=UTF-8″

FetchRequest uses the following command:

  • GET request:
fetchRequest('app/book'.'GET')
    .then( res=>{
        // The request succeeded
        if(res.header.statusCode == 'success') {// The statusCode in the header returned by the server is success

        }else{
            // The server returns an exception. Set the exception information to be saved in header.msgarray [0].desc
            console.log(res.header.msgArray[0].desc); }}).catch( err=>{ 
        // The request failed
    })Copy the code
  • POST request:
let params = {
    username:'admin',
    password:'123456'
}
fetchRequest('app/signin'.'POST'.params)
    .then( res= >{
        // The request succeeded
        if(res.header.statusCode = = 'success') {// The statusCode in the header returned by the server is success

        }else{
            // The server returns an exception. Set the exception information to be saved in header.msgarray [0].desc
            console.log(res.header.msgArray[0].desc); }}). Catch (err=>{// request failed})Copy the code


Fetch Timeout processing

Since the native Fetch API does not support the timeout attribute, if the project needs to control the timeout time of THE Fetch request, the Fetch request can be further encapsulated to implement the timeout function, with the code as follows:

FetchRequest Timeout processing encapsulation

/** * allow fetch to timeout * timeout does not mean connection timeout, it means the response time of the request, including the connection time of the request, the server processing time, and the server response time. This request is not abort. It is still sent to the server in the background, but the response to this request is discarded@param{Promise} fetch_PROMISE fetch Indicates the Promise * returned by the request@param {number} [timeout=10000] unit: ms. The default timeout period is10Seconds *@returnReturns the Promise * /function timeout_fetch(fetch_promise,timeout = 10000) {
    let timeout_fn = null; 

    //This is a promise that can be rejectedlet timeout_promise = new Promise(function(resolve, reject) {
        timeout_fn = function() {
            reject('timeout promise');
        };
    });

    //Promise. Race is used here to pass in callbacks for subsequent bindings as soon as possible as resolve or rejectlet abortable_promise = Promise.race([
        fetch_promise,
        timeout_promise
    ]);

    setTimeout(function() {
        timeout_fn();
    }, timeout);

    return abortable_promise ;
}

let common_url = 'http://192.168.1.1:8080/';  //Server addresslet token = ' '; / * * *@param{string} URL Interface address *@param{string} method Request methods: GET and POST, uppercase * only@param {JSON} [params=' '] body request parameter, which defaults to empty *@returnReturns the Promise * /function fetchRequest(url, method, params = ' ') {let header = {
        "Content-Type": "application/json; charset=UTF-8"."accesstoken":token  //The token returned by the user after login. Some interfaces involving user data need to add token} in the header.console.log('request url:',url,params);  //Print request parametersif(params == ' ') {//If the network request has parametersreturn new Promise(function (resolve, reject) {
            timeout_fetch(fetch(common_url + url, {
                method: method,
                headers: header
            })).then((response) => response.json())
                .then((responseData) => {
                    console.log('res:',url,responseData);  //Resolve (responseData); })
                .catch( (err) => {
                    console.log('err:',url, err);     //Reject (ERR) Data returned when a network request fails. });
        });
    }else{// If there are no parameters in the network requestreturn new Promise(function (resolve, reject) {
            timeout_fetch(fetch(common_url + url, {
                method: method,
                headers: header,
                body:JSON.stringify(params)   //The body argument, which usually needs to be converted to a string before the server can parse it})).then((response) => response.json())
                .then((responseData) => {
                    console.log('res:',url, responseData);   //Resolve (responseData); }).catch( (err) => {
                    console.log('err:',url, err);   //Reject (ERR) Data returned when a network request fails. }); }); }}Copy the code

FetchRequest network requests with timeout processing are used in the same way as those without timeout processing. A wrapper for timeout handling of fetch network requests is written in the following article:

Make fetch also timeout