前言:

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

什么是fetch?

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

WHY fetch?

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

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json'; xhr.onload = function() {
console.log(xhr.response);
}; xhr.onerror = function() {
console.log("Oops, error");
}; xhr.send();

  

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

 
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
 

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

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

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

  

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

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

 
// Async/Await requirements: Latest Chrome/FF browser or Babel: https://babeljs.io/docs/plugins/transform-async-to-generator/
// Fetch requirements: Latest Chrome/FF browser or Github fetch polyfill: https://github.com/github/fetch // async function
async function fetchAsync () {
// await response of fetch call
let response = await fetch('https://api.github.com');
// only proceed once promise is resolved
let data = await response.json();
// only proceed once second promise is resolved
return data;
} // trigger async function
// log response or catch error of fetch promise
fetchAsync()
.then(data => console.log(data))
.catch(reason => console.log(reason.message))
 

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

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

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

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

   

  

基本使用方法:

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

 
 fetch("/getAllProduct").then(function(res) {
return res.json();
}).then(function (data) {
if (data.code == 200) {
console.log('获取到所有产品' ,data.data);
that.props.addAllProduct(data.data);
} else {
console.log(data.message);
}
})
 

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

 
/* 对客户端的返回数据封装
* @param [code] (number) code为返回的状态码
* @param [message] (string) message为返回的信息
* @param [data] (any) data是可选的,为返回给前端的数据
*/
// 注意: retrunJson中的res为node处理接口的回调函数中的res,这个是必须的。
function returnJson(res, code, message, data) {
var response = {
code: code,
message: message
};
if (typeof data !== 'undefined') {
response.data = data;
}
res.json(response);
   // 返回这个请求之后,必须要 res.end()表示请求的结束,否则后台可能会崩溃。
res.end();
} router.post('/register', function (req, res) {
let userName = req.body.username,
password = req.body.password,
passwordAgain = req.body.passwordAgain,
type = req.body.type;
console.log(userName, password, type);
if (type == 1) {
if (password == passwordAgain) {
let managerId = uuidv1(); console.log(userName, password, passwordAgain); var newUser = new Manager({
name: userName,
password: password,
type: req.body.type,
managerId: managerId
}); Manager.find(userName, function (err, user) {
if (err) {
returnJson(res, 5001, '服务器错误,注册失败');
} else {
if (user !== null) {
returnJson(res, 4003, "此用户已经注册!");
} else {
// 如果符合条件,就注册该用户,将数据保存在数据库。
newUser.save(function (err, user) {
if (err) {
// 服务器端错误,失败返回状态码500
returnJson(res, 500, "用户注册失败!");
} else {
// user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。
returnJson(res, 200, "用户注册成功!", user);
}
});
}
}
});
} else {
returnJson(res, 4001, "用户两次输入密码不一致!");
}
} else if( type == 2) { if (password == passwordAgain) {
let userId = uuidv1(); console.log(userName, password, passwordAgain); var newUser = new User({
name: userName,
password: password,
type: req.body.type,
userId: userId
}); User.find(userName, function (err, user) {
if (err) {
returnJson(res, 5001, '服务器错误,注册失败');
} else {
if (user !== null) {
returnJson(res, 4003, "此用户已经注册!");
} else {
// 如果符合条件,就注册该用户,将数据保存在数据库。
newUser.save(function (err, user) {
if (err) {
// 服务器端错误,失败返回状态码500
returnJson(res, 500, "用户注册失败!");
} else {
// user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。
returnJson(res, 200, "用户注册成功!", user);
}
});
}
}
});
} else {
returnJson(res, 4001, "用户两次输入密码不一致!");
}
}
});
 

这样,我们就可以处理一个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定义如下:

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

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

最新文章

  1. IOS调用系统声音(键盘声音)
  2. Java final修饰符
  3. android 读取SQLite android could not open the database in read/write mode错误
  4. PHP 魔术变量
  5. HDU 4870 Rating 概率DP
  6. socket.io遇到的问题
  7. 使用sqlserver日期函数获取当前日期
  8. OSSEC - Agent端查看命令
  9. 【Android Studio】No JVM installation found
  10. PHP中级篇 Apache配置httpd-vhosts虚拟主机总结及注意事项[OK]
  11. H5缓存
  12. 浏览器出现Cannot set property 'onclick' of null的问题
  13. JS-使用工厂方法创建对象
  14. R.java文件介绍
  15. [luogu4264][USACO18FEB]Teleportation
  16. shiro自定义realm认证(五)
  17. Javascript经典算法学习1:产生随机数组的辅助类
  18. 转 php简单伪静态实例
  19. 牛顿法/拟牛顿法/DFP/BFGS/L-BFGS算法
  20. Ext NumberField使用

热门文章

  1. Maven简单介绍(Maven是什么)
  2. 百度 谷歌 Twitter,这么多短链接服务(Short Url)究竟哪家强?
  3. HH实习(hpu1287)(斐波那契运用)
  4. 晋IT分享成长沙龙集锦
  5. hadoop相关
  6. ORA-01261: Parameter db_recovery_file_dest destination string cannot be translat
  7. xmanager使用
  8. Creative Cloud 安装出错,错误代码:207
  9. IP地址的正则表达式写法
  10. 利用SignalR来同步更新Winfrom