react-native fetch的具体使用方法


Posted in Javascript onNovember 01, 2017

在前端快速发展地过程中,为了契合更好的设计模式,产生了 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)})

返回的数据:

react-native fetch的具体使用方法

这样就很快速地完成了一次网络请求,我们发现返回的数据也比之前的 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。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS控制输入框内字符串长度
May 21 Javascript
JavaScript跨域方法汇总
Oct 16 Javascript
JQuery插件Marquee.js实现无缝滚动效果
Apr 26 Javascript
JavaScript中自带的 reduce()方法使用示例详解
Aug 10 Javascript
Java  Spring 事务回滚详解
Oct 17 Javascript
vue中渐进过渡效果实现
Oct 27 Javascript
jquery获取table指定行和列的数据方法(当前选中行、列)
Nov 07 Javascript
js仿百度音乐全选操作
Jan 13 Javascript
详解前后端分离之VueJS前端
May 24 Javascript
JS通过调用微信API实现微信支付功能的方法示例
Jun 29 Javascript
js中的 || 与 && 运算符详解
May 24 Javascript
Vue实现根据hash高亮选项卡
May 27 Javascript
Vue异步加载about组件
Oct 31 #Javascript
微信小程序顶部可滚动导航效果
Oct 31 #Javascript
React Native使用Modal自定义分享界面的示例代码
Oct 31 #Javascript
Bootstrap3.3.7导航栏下拉菜单鼠标滑过展开效果
Oct 31 #Javascript
使用nvm管理不同版本的node与npm的方法
Oct 31 #Javascript
javascript高级模块化require.js的具体使用方法
Oct 31 #Javascript
JS简单实现点击跳转登陆邮箱功能的方法
Oct 31 #Javascript
You might like
Admin generator, filters and I18n
2011/10/06 PHP
使用 laravel sms 构建短信验证码发送校验功能
2017/11/06 PHP
PHP 计算两个时间段之间交集的天数示例
2019/10/24 PHP
在textarea中屏蔽js的某个function的javascript代码
2007/04/20 Javascript
来自chinaz的ajax获取评论代码
2008/05/03 Javascript
改进UCHOME的记录发布,增强可访问性用户体验
2011/01/17 Javascript
JS清空多文本框、文本域示例代码
2014/02/24 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
2015/03/10 Javascript
js验证上传图片的方法
2015/05/12 Javascript
纯javascript实现的小游戏《Flappy Pig》实例
2015/07/27 Javascript
JavaScript数据结构链表知识详解
2016/11/21 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
js实现仿购物车加减效果
2017/03/01 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
jQuery插件FusionCharts实现的3D帕累托图效果示例【附demo源码】
2017/03/25 jQuery
[原创]js实现保存文本框内容为本地文件兼容IE,chrome,火狐浏览器
2018/02/14 Javascript
Vue中使用vee-validate表单验证的方法
2018/05/09 Javascript
VeeValidate 的使用场景以及配置详解
2019/01/11 Javascript
[01:14]3.19DOTA2发布会 三代刀塔人第二代
2014/03/25 DOTA
[05:34]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY第二弹
2014/06/25 DOTA
详解Python中的from..import绝对导入语句
2016/06/21 Python
win7上python2.7连接mysql数据库的方法
2017/01/14 Python
Python中实现switch功能实例解析
2018/01/11 Python
Python3 中把txt数据文件读入到矩阵中的方法
2018/04/27 Python
Python产生一个数值范围内的不重复的随机数的实现方法
2019/08/21 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
python调用API接口实现登陆短信验证
2020/05/10 Python
深入剖析HTML5 内联框架iFrame
2016/05/04 HTML / CSS
Carter’s官方旗舰店:美国受欢迎的婴童服装品牌
2018/01/21 全球购物
会计专业毕业生自我鉴定
2013/10/29 职场文书
大学生毕业求职自荐书范文
2014/02/04 职场文书
关于感谢信的范文
2015/01/23 职场文书
2015年领导干部廉洁自律工作总结
2015/05/26 职场文书
高考百日冲刺决心书
2015/09/23 职场文书
Python编程根据字典列表相同键的值进行合并
2021/10/05 Python
《遗弃》开发商删推文要跑路?官方回应:还在开发
2022/04/03 其他游戏