Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

ReactNative——fetch封装新姿势

$
0
0

React和ReactNative 的网络请求使用的是fetch

关于基本的POST和GET请求以及异步变同步就不再描述,看看API的介绍。

网络请求封装要完成的内容有:

1、基本功能(网络请求)

2、统一处理

异常处理
不同错误码处理

3、可定制loading弹窗提示

4 、可定制Header

5、超时处理

6、登陆验证token处理

7、url 特殊字符处理

8、网络请求日志打印

超级方便的调试技巧

const WrapFetch = (url, req, config) => {
  //默认参数
  let request = {
    method: 'GET',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + (window.token || '')
    }
  };

  //配置参数
  //默认不显示进度条,如果需要显示config传参{ showLoading: true}
  const cnf = Object.assign({}, {
    showLoading: false,
    showLoginView: true
  }, config);

   //默认header,如果需要特殊处理可通过传参改变
  if (req && req.headers) {
    const mergeHeader =  Object.assign({}, request.headers, req.headers);
    request.headers = mergeHeader;
    delete req.headers;
  }

  //merge
  const merge = Object.assign({}, request, req);


  //去掉url中可能存在的//
  url = url.replace(/([^:])\/\//, '$1/');

  if (__DEV__) {
    console.log('请求->', url, '\n', JSON.stringify(merge, null, 2));
  }

  return new Promise((resolve, reject) => {
    let isServerOk = true;
    let httpStatus = 200;

    //超时优化
    let httpTimeout = setTimeout(() => {
      const err = {
        code: 'S-000002',
        message: '网络超时'
      };
      //计时开始,显示弹窗
      if (cnf.showLoading) {
        msg.emit('ModalLoading:hide');
      }
      msg.emit('app:tip', err.code + '-' + err.message);
      reject(err);
    }, 5000);


    //如果配置showLoading为true,显示modalloading
    if (cnf.showLoading) {
      msg.emit('ModalLoading:show');
    }


    fetch(url, merge)
      .then(res => {
        //清除网络超时
        clearTimeout(httpTimeout);
        //当前的http的状态
        httpStatus = res.status;
        //判断server是不是异常状态404500等
        isServerOk = !!(res.status >= 200 && res.status < 300);
        //promise
        return res.json();
      })
      .then((res) => {
        //hide
        if (cnf.showLoading) {
          msg.emit('ModalLoading:hide');
        }
        if (isServerOk&&res.code===1000) {
          if (__DEV__) {
            console.info('响应->', httpStatus, url, '\n', res);
          }
          //数据正确返回
          resolve(res);
        } else {
          if (__DEV__) {
            console.info('响应->', url, httpStatus, '\n', res);
          }
          if (httpStatus == 401) {
            if(cnf.showLoginView){
              msg.emit('tokenInvalid');
            }
            //token过期或者校验错误,将token清除
            AsyncStorage.setItem('token', '');
            window.token = '';
          } else {
            if (res.code === 'N-000001') {
              // 系统异常隐藏
              msg.emit('app:tip', '您的网络不给力:(');
            } else {
              msg.emit('app:tip', res.message);
            }
          }
          reject(res);
        }
      })
      .catch((err) => {
        //清除网络超时
        clearTimeout(httpTimeout);

        if (cnf.showLoading) {
          msg.emit('ModalLoading:hide');
        }

        if (__DEV__) {
          console.info('WrapFetchError:', err);
        }

        msg.emit('app:tip', '您的网络不给力:(');
        reject({
          code: 'N-000001',
          message: '网络错误'
        });
      })
      .done();
  });
};


export default WrapFetch;

msg.emit()是iflux-native框架的事件方法,用于调用相关方法

具体实现需要根据后端定义的接口状态码,使其符合你的项目。

作者:TaooLee 发表于2017/9/11 14:28:24 原文链接
阅读:208 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>