前言:

  fetch是用来取代传统的XMLHttpRequest的。 它的优点很多,包括链式调用的语法、返回promise等。

什么是fetch?

  fetch api是基于promise的设计,它是为了取代传统xhr的不合理的写法而生的。

WHY fetch?

  xhr请求写起来非常的混乱,如下所示:

  1. var xhr = new XMLHttpRequest();
  2. xhr.open('GET', url);
  3. xhr.responseType = 'json';
  4.  
  5. xhr.onload = function() {
  6. console.log(xhr.response);
  7. };
  8.  
  9. xhr.onerror = function() {
  10. console.log("Oops, error");
  11. };
  12.  
  13. xhr.send();

  

  但是使用fetch之后,如下所示:

 
  1. fetch(url).then(function(response) {
  2. return response.json();
  3. }).then(function(data) {
  4. console.log(data);
  5. }).catch(function(e) {
  6. console.log("Oops, error");
  7. });
 

  这种链式调用的风格看上去会非常舒服。

  如果我们再使用了箭头函数就会更加简洁了。

  1. fetch(url).then(response => response.json())
  2. .then(data => console.log(data))
  3. .catch(e => console.log("Oops, error", e))

  

  通过使用fetch api,可以将传统的xhr的粗糙的使用方法转化的如此精简,实在是好!

  但是呢? 使用Promise,还是可以很明显看到callback的使用,不急,我们还可以使用 async、await :

 
  1. // Async/Await requirements: Latest Chrome/FF browser or Babel: https://babeljs.io/docs/plugins/transform-async-to-generator/
  2. // Fetch requirements: Latest Chrome/FF browser or Github fetch polyfill: https://github.com/github/fetch
  3.  
  4. // async function
  5. async function fetchAsync () {
  6. // await response of fetch call
  7. let response = await fetch('https://api.github.com');
  8. // only proceed once promise is resolved
  9. let data = await response.json();
  10. // only proceed once second promise is resolved
  11. return data;
  12. }
  13.  
  14. // trigger async function
  15. // log response or catch error of fetch promise
  16. fetchAsync()
  17. .then(data => console.log(data))
  18. .catch(reason => console.log(reason.message))
 

  这样看上去是不是就好多了呢?

注意: 对于async和await的使用还是很明确的,就是一般我们在一个异步函数之前添加 await 关键词,然后在这个 await 的相关代码外面使用的时 async 函数,这样的结合才是合适的。

利用 async 和 await,我们就可以像写同步代码一样来写异步代码啦! 

但是呢,目前async 和 await 的支持性还不是很好,目前还无法在一般的浏览器中使用!

   

  

基本使用方法:

fetch必须接受一个资源路径作为参数,并且返回了一个promise,所以我们可以直接使用链式调用的方式。

 
  1. fetch("/getAllProduct").then(function(res) {
  2. return res.json();
  3. }).then(function (data) {
  4. if (data.code == 200) {
  5. console.log('获取到所有产品' ,data.data);
  6. that.props.addAllProduct(data.data);
  7. } else {
  8. console.log(data.message);
  9. }
  10. })
 

这样,我们就可以发送一个ajax请求。

 
  1. /* 对客户端的返回数据封装
  2. * @param [code] (number) code为返回的状态码
  3. * @param [message] (string) message为返回的信息
  4. * @param [data] (any) data是可选的,为返回给前端的数据
  5. */
  6. // 注意: retrunJson中的res为node处理接口的回调函数中的res,这个是必须的。
  7. function returnJson(res, code, message, data) {
  8. var response = {
  9. code: code,
  10. message: message
  11. };
  12. if (typeof data !== 'undefined') {
  13. response.data = data;
  14. }
  15. res.json(response);
       // 返回这个请求之后,必须要 res.end()表示请求的结束,否则后台可能会崩溃。
  16. res.end();
  17. }
  18.  
  19. router.post('/register', function (req, res) {
  20. let userName = req.body.username,
  21. password = req.body.password,
  22. passwordAgain = req.body.passwordAgain,
  23. type = req.body.type;
  24. console.log(userName, password, type);
  25. if (type == 1) {
  26. if (password == passwordAgain) {
  27. let managerId = uuidv1();
  28.  
  29. console.log(userName, password, passwordAgain);
  30.  
  31. var newUser = new Manager({
  32. name: userName,
  33. password: password,
  34. type: req.body.type,
  35. managerId: managerId
  36. });
  37.  
  38. Manager.find(userName, function (err, user) {
  39. if (err) {
  40. returnJson(res, 5001, '服务器错误,注册失败');
  41. } else {
  42. if (user !== null) {
  43. returnJson(res, 4003, "此用户已经注册!");
  44. } else {
  45. // 如果符合条件,就注册该用户,将数据保存在数据库。
  46. newUser.save(function (err, user) {
  47. if (err) {
  48. // 服务器端错误,失败返回状态码500
  49. returnJson(res, 500, "用户注册失败!");
  50. } else {
  51. // user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。
  52. returnJson(res, 200, "用户注册成功!", user);
  53. }
  54. });
  55. }
  56. }
  57. });
  58. } else {
  59. returnJson(res, 4001, "用户两次输入密码不一致!");
  60. }
  61. } else if( type == 2) {
  62.  
  63. if (password == passwordAgain) {
  64. let userId = uuidv1();
  65.  
  66. console.log(userName, password, passwordAgain);
  67.  
  68. var newUser = new User({
  69. name: userName,
  70. password: password,
  71. type: req.body.type,
  72. userId: userId
  73. });
  74.  
  75. User.find(userName, function (err, user) {
  76. if (err) {
  77. returnJson(res, 5001, '服务器错误,注册失败');
  78. } else {
  79. if (user !== null) {
  80. returnJson(res, 4003, "此用户已经注册!");
  81. } else {
  82. // 如果符合条件,就注册该用户,将数据保存在数据库。
  83. newUser.save(function (err, user) {
  84. if (err) {
  85. // 服务器端错误,失败返回状态码500
  86. returnJson(res, 500, "用户注册失败!");
  87. } else {
  88. // user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。
  89. returnJson(res, 200, "用户注册成功!", user);
  90. }
  91. });
  92. }
  93. }
  94. });
  95. } else {
  96. returnJson(res, 4001, "用户两次输入密码不一致!");
  97. }
  98. }
  99. });
 

这样,我们就可以处理一个ajax请求。

注意点:

1、fetch() 返回的是一个Promise对象。

  fetch使用的promise对象可以使得我们使用同步的方式写异步函数。

2、 fetch api是可以结合 async 和 await 来使用的。

  fetch是基于promise实现的,但是使用promise的写法,我们还是可以看到callback的影子,如果结合 async和await来使用,还是非常不错的。

3、 Fetch api 提供的spi囊括但是不限于xhr的所有功能。

4、 fetch api 可以跨域。

  参考: https://fetch.spec.whatwg.org/#http-cors-protocol

  跨域请求必须包括  Origin 作为header.

    以上。

    我们在发送fetch请求的时候就会使用到CORS协议,尽管这些对于开发者来说是透明的,但是浏览器还是会发送 origin 字段。

5、fetch提供了对request和response对象的通用定义。

  Fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。所以在一个Fetch请求中,完全可以只使用Request 和 Response两个对象,通过Request 设置参数,通过Response 对返回值进行处理。 

 所以,我们可以将一个fetch定义如下:

  1. var myHeaders = new Headers();
  2. myHeaders.append('Content-Type', 'image/jpeg');
  3. var option = { method: 'GET',
  4. headers: myHeaders,
  5. mode: 'cors',
  6. cache: 'default' };
  7. var myRequest = new Request('https://api.github.com/users/mzabriskie',option);
  8. fetch(myRequest).then(function(response) {
  9. ...
  10. });

本文转自:https://www.cnblogs.com/zhuzhenwei918/p/7249691.html

关于fetch的更多相关文章

  1. Git 少用 Pull 多用 Fetch 和 Merge

    本文有点长而且有点乱,但就像Mark Twain Blaise Pascal的笑话里说的那样:我没有时间让它更短些.在Git的邮件列表里有很多关于本文的讨论,我会尽量把其中相关的观点列在下面. 我最常 ...

  2. git提示:Fatal:could not fetch refs from ....

    在git服务器上新建项目提示: Fatal:could not fetch refs from git..... 百度搜索毫无头绪,最后FQgoogle,找到这篇文章http://www.voidcn ...

  3. sublime 插件推荐: Nettuts+ Fetch

    Nettuts+ Fetch github地址:Nettuts-Fetch 在sublime中直接用 ctrl+shift+P -> pci -> Nettuts-Fetch 即可下载 这 ...

  4. git pull和git fetch的区别

    Git中从远程的分支获取最新的版本到本地有这样2个命令:1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge Git fetch origin master git log ...

  5. Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)

    假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下: 假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: Session session=H ...

  6. SQL Server 2012提供的OFFSET/FETCH NEXT与Row_Number()对比测试(转)

    原文地址:http://www.cnblogs.com/downmoon/archive/2012/04/19/2456451.html 在<SQL Server 2012服务端使用OFFSET ...

  7. Attempt to fetch logical page (...) in database 2 failed. It belongs to allocation unit xxxx not to xxx

    今天一个同事说在一个生产库执行某个存储过程,遇到了错误: Fatal error 605 occurred at jul 29 2014 我试着执行该存储过程,结果出现下面错误,每次执行该存储过程,得 ...

  8. Fetch:下一代 Ajax 技术

    Ajax,2005年诞生的技术,至今已持续了 10 年.它是一种在客户端创建一个异步请求的技术,本质上它不算创新,是一组技术的组合.它的核心对象是 XMLHttpRequest. 简单回顾下历史 19 ...

  9. 在 JS 中使用 fetch 更加高效地进行网络请求

    在前端快速发展地过程中,为了契合更好的设计模式,产生了 fetch 框架,此文将简要介绍下 fetch 的基本使用. 我的源博客地址:http://blog.parryqiu.com/2016/03/ ...

  10. 解决:error: Cannot fetch repo (TypeError: expected string or buffer)

    同步源码,问题重现: Fetching project platform/external/libopus Fetching project repo error: Cannot fetch repo ...

随机推荐

  1. SPOJ 4491

    不妨先把所有要求的素数的对的个数写出来 f(2)=u(1)G(2)+u(2)*G(2*2)+u(3)*G(2*3)+.....u(k2)*G(2*k2) f(3)=u(1)G(3)+u(2)*G(2* ...

  2. STM32F407VG (四)时钟配置

    1.STM32 F407VG 的starup_stm32f40_41xxx.s的例如以下位置调用 IMPORT SystemInit,之后调用main函数,所以 进入main函数时候就已经自己主动完毕 ...

  3. Oracle 12c agent install for windows

    在Oracle EM12c 中部署agent的方法分两种,一种是通过EM12c的控制台通过ssh直接把agent"推送"安装到被管理端.这样的方法在linux平台的OMS和被管理端 ...

  4. hadoop 2.6.0 分布式 + Spark 1.1.0 集群环境

    配置jdk 执行 sudo apt-get install openjdk-7-jdk jdk被安装到了 /usr/lib/jvm/ 目录 配置hosts 使用 vim 打开 /etc/hosts, ...

  5. C++线程传参数

    struct TThreadParam { LPVOID pThis; int visionIndex; }; class CMilTestDlg : public CDialog { // Cons ...

  6. sql server 查询某数据库中包含某字段的所有表格

    场景:查询DNMes数据库中所有包含RFID字段的表名 sql语句: select object_name(id) objName,Name as colName from syscolumns wh ...

  7. String Comparison(C#)

    When comparing programmatic strings, you should always use StringComparison.Ordinal or StringCompari ...

  8. Swift 闭包中 self? 的由来

    class UIViewSpringAnimator: SwipeAnimator { // 动画完成的闭包 var completion:((Bool) ->Void)? func addCo ...

  9. Docker学习笔记(1)----认识Docker

    1. 什么Docker? Docker是一个能把开发的应用程序自动部署到容器的引擎,它使用go语言编写的开源引擎,它在github上面个的地址为:https://github.com/docker/d ...

  10. UVA-11584 Partitioning by Palindromes 动态规划 回文串的最少个数

    题目链接:https://cn.vjudge.net/problem/UVA-11584 题意 给一个字符串序列,问回文串的最少个数. 例:aaadbccb 分为aaa, d, bccb三份 n< ...