ES6/7/8新特性Promise,async,await,fetch带我们逃离异步回调的深渊
2017-07-20 11:59
771 查看
Promise:
在ES6以前如果我们需要在js中进行异步处理,大多数都是通过使用回调函数的方式来解决问题,如果简单的异步处理,回调函数的方式看起来还是比较优雅的,逼格还有点高,但是如果异步操作很多,回调嵌套就很深,代码看起来就会特别别扭,维护起来成本也会变高这个时候ES6带来Promise这个新特性,这个方法很好的解决了深层次异步嵌套的问题,我们在写代码的时候可以采用类似linux流式的书写方式:
例如:
这样的异步操作看起来就非常直观了。下面是一个完整Proimise例子
reslove代表处理成功,对应后面的then,reject代表处理失败,对应后面的catch,resolve和reject里面值可以是字符串,也可以是对象,这个值可以理解成Promise的返回值。
Promise不经有then,catch,还有all,race,具体怎么用找度娘。其实就是同时获取多个Promise对象返回值得操作。
看见上面的Promise的用法,熟悉jquery的司机是不是有点似曾相识的赶脚。其实在jquery1.5版本以后,$.ajax就可以使用上面那种流式的操作了,开始逐渐摈弃回调的方式。
如果你还在使用success,error的回调函数的这种方式,呵呵。。。。
jquey使用了Deferred的方式实现的类似Promise的功能,在jquery1.7以后,.Deferred被独立了出来,.Deferred和Promise的使用方式几乎就是一个模子里面刻出来的:
讲完了Proimise,现在来讲讲async和await
async,await语法糖
async和await是ES7新增的规范,两个规范可以看成一队连体婴,他们要一起出现才有效果:
要注意await只能在async中使用,不然是没有效果的。其实async 和await联合起来使用相当于替代了Promise的then和catch方法,将async低昂一的函数里面的代码由异步变成了同步阻塞式,只有当await定义的行数执行完了代码才会继续往下执行,同时await还有有返回值,他的返回值在上面这个例子中就是resolve,reject的值需要通过try {}catch(err){},捕获:
await后面的应该跟一个Promise的对象或者fetch(后面讲),不然结果会有点怪怪的,我直接在后面加一个setTimeout,结果然我很是不解,有兴趣的可以分别执行下面两段代码,结果超乎你的想象:
其实个人感觉还是喜欢直接使用Promise实现异步操作,感觉async和await有点把事情搞复杂了。当然居然人家把他作为了ES7的规范,而且是为数不多的规范,那么他就有用武之地。特别是如果我们有时候js代码需要同步操作的时候。
fetch:
这个方法是ES2017中新增的特性,这个特性出来后给人一种传统ajax已死的感觉,其实它的作用是替代浏览器原生的XMLHttpRequest异步请求,我们在日常的开发中,基本不会自己去写XMLHttpRequest,主要是太复杂了,都是使用已经封装好了的各种插,件常用的有jquery,npm包管理工具也提供了axios,request等模块。而有了fetch后我们就可以在不用这些插件的情况下快速简单的实现异步请求了:
get请求:
post请求:
上面这种写法其实和我们常用的ajax插件写法就比较像了,但是要注意目前原生的fetch还不支持jsonp的请求方式,如果需要实现jsonp,需要安装npm包fetchJ-jsonp,使用方式:
我们可以通过new Header构建我们的请求头:
请求头也是可以被索引:
fetch可以设置不同的模式使得请求有效. 模式可在fetch方法的第二个参数对象中定义.
通过上面fetch的使用方式,可以看出他和Promise的使用方式非常相像,fetch其实返回的就是一个Promise对象,async,await也就和fetch是完美兼容了,我们可以使用async,await实现代码的同步:
这篇文章主要梳理了一下Promise,async,await,fetch之间的关系,Primise是基础,async,await,fetch是踩在Promise的肩膀上。
在ES6以前如果我们需要在js中进行异步处理,大多数都是通过使用回调函数的方式来解决问题,如果简单的异步处理,回调函数的方式看起来还是比较优雅的,逼格还有点高,但是如果异步操作很多,回调嵌套就很深,代码看起来就会特别别扭,维护起来成本也会变高这个时候ES6带来Promise这个新特性,这个方法很好的解决了深层次异步嵌套的问题,我们在写代码的时候可以采用类似linux流式的书写方式:
例如:
flow().then(function(success){}).catch(function(error){})
这样的异步操作看起来就非常直观了。下面是一个完整Proimise例子
function flow(flag){ //promise是一个构造函数,内部接收一个回调函数。 //回调函数内部有两个参数,reslove是执行成功的时候调用的,reject是失败调用的 var promise = new Promise(function(reslove,reject){ setTimeout(function(){//模拟异步操作 if(flag){ reslove(true);//处理成功 }else{ reject(false)处理失败 } },5000) }); return promise; } //flow返回的是一个Promise对象,这样我们就能通过下面的方式来的处理异步操作了。 //调用该函数 flow().then(function(success){ }).catch(function(error){ //处理失败返回 });
reslove代表处理成功,对应后面的then,reject代表处理失败,对应后面的catch,resolve和reject里面值可以是字符串,也可以是对象,这个值可以理解成Promise的返回值。
Promise不经有then,catch,还有all,race,具体怎么用找度娘。其实就是同时获取多个Promise对象返回值得操作。
看见上面的Promise的用法,熟悉jquery的司机是不是有点似曾相识的赶脚。其实在jquery1.5版本以后,$.ajax就可以使用上面那种流式的操作了,开始逐渐摈弃回调的方式。
$.ajax({}).then(function(result){}).fail(function(error){})
如果你还在使用success,error的回调函数的这种方式,呵呵。。。。
jquey使用了Deferred的方式实现的类似Promise的功能,在jquery1.7以后,.Deferred被独立了出来,.Deferred和Promise的使用方式几乎就是一个模子里面刻出来的:
function runAsync(){ var def = $.Deferred(); //做一些异步操作 setTimeout(function(){//模拟异步操作 def.resolve('随便什么数据'); }, 2000); return def; } runAsync().then(function(data){ console.log(data) });
讲完了Proimise,现在来讲讲async和await
async,await语法糖
async和await是ES7新增的规范,两个规范可以看成一队连体婴,他们要一起出现才有效果:
var stop= function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, time); }) }; var start = async function () { // 在这里使用起来就像同步代码那样直观 console.log('start'); var result = await stop(3000); console.log('end'); }; start();
要注意await只能在async中使用,不然是没有效果的。其实async 和await联合起来使用相当于替代了Promise的then和catch方法,将async低昂一的函数里面的代码由异步变成了同步阻塞式,只有当await定义的行数执行完了代码才会继续往下执行,同时await还有有返回值,他的返回值在上面这个例子中就是resolve,reject的值需要通过try {}catch(err){},捕获:
var start = async function () { // 在这里使用起来就像同步代码那样直观 console.log('start'); try{ await stop(3000); }catch(err){ console.log(err); } console.log('end'); }; start();
await后面的应该跟一个Promise的对象或者fetch(后面讲),不然结果会有点怪怪的,我直接在后面加一个setTimeout,结果然我很是不解,有兴趣的可以分别执行下面两段代码,结果超乎你的想象:
var start1 = async function () { // 在这里使用起来就像同步代码那样直观 console.log('start'); var a = await setTimeout(function(){console.log("---")},5000) console.log('end'+a); }; start1();console.log("----");
var start2 = async function () { // 在这里使用起来就像同步代码那样直观 console.log('start'); var a = await setTimeout(function(){console.log("---")},5000) console.log('end'+a); }; start();console.log("----");for(var i=0; i<10;i++){console.log(i)}
其实个人感觉还是喜欢直接使用Promise实现异步操作,感觉async和await有点把事情搞复杂了。当然居然人家把他作为了ES7的规范,而且是为数不多的规范,那么他就有用武之地。特别是如果我们有时候js代码需要同步操作的时候。
fetch:
这个方法是ES2017中新增的特性,这个特性出来后给人一种传统ajax已死的感觉,其实它的作用是替代浏览器原生的XMLHttpRequest异步请求,我们在日常的开发中,基本不会自己去写XMLHttpRequest,主要是太复杂了,都是使用已经封装好了的各种插,件常用的有jquery,npm包管理工具也提供了axios,request等模块。而有了fetch后我们就可以在不用这些插件的情况下快速简单的实现异步请求了:
get请求:
var word = '123', url = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd='+word+'&json=1&p=3'; fetch(url,{mode: "no-cors"}).then(function(response) { return response; }).then(function(data) { console.log(data); }).catch(function(e) { console.log("Oops, error"); });
post请求:
var headers = new Headers(); headers.append("Content-Type", "application/json;"); fetch(url, { method: 'post', headers: headers, body: JSON.stringify({ date: '2016-10-08', time: '15:16:00' }) });
上面这种写法其实和我们常用的ajax插件写法就比较像了,但是要注意目前原生的fetch还不支持jsonp的请求方式,如果需要实现jsonp,需要安装npm包fetchJ-jsonp,使用方式:
fetchJsonp(url, { timeout: 3000, jsonpCallback: 'callback' }).then(function(response) { console.log(response.json()); }).catch(function(e) { console.log(e) });
我们可以通过new Header构建我们的请求头:
var headers = new Headers(); headers.append("Content-Type", "text/html"); fetch(url,{ headers: headers });
请求头也是可以被索引:
var header = new Headers({ "Content-Type": "text/plain" }); console.log(header.has("Content-Type")); //true console.log(header.has("Content-Length")); //false
fetch可以设置不同的模式使得请求有效. 模式可在fetch方法的第二个参数对象中定义.
通过上面fetch的使用方式,可以看出他和Promise的使用方式非常相像,fetch其实返回的就是一个Promise对象,async,await也就和fetch是完美兼容了,我们可以使用async,await实现代码的同步:
(async ()=>{ try { let res = await fetch(url, {mode: 'no-cors'});//等待fetch被resolve()后才能继续执行 console.log(res); } catch(e) { console.log(e); } })();
这篇文章主要梳理了一下Promise,async,await,fetch之间的关系,Primise是基础,async,await,fetch是踩在Promise的肩膀上。
相关文章推荐
- Promise原理讲解 async+await应用(异步回调解决方案)
- Node.js异步控制流:回调、事件、Promise和async/await
- 前端的异步解决方案之Promise和Await-Async
- NodeJS-Promise、await、async异步变同步
- 使用Promise和async-await实现的一个异步遍历+同步执行任务的实例
- 理解异步之美:Promise与async await(一)
- Promise,同步异步,Async/await
- 论完爆nodejs吹的异步回调的异步模型async await
- async/await与promise(nodejs中的异步操作问题)
- ES6系列文章 异步神器async-await
- ES6 Promise对象解决异步回调
- 理解异步之美:Promise 与 async await(二)
- 前端的异步解决方案之Promise和Await-Async
- ES6 Promise 和 Async/await的使用
- 关于Promise,Generator,async / await 对异步的处理
- async/await 带你逃离回调地狱
- [完结篇] - 理解异步之美 --- promise与async await (三)
- 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
- ES6总结--Promise 、Generator 、Async/Await
- 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题 第四节:一些指令总结 定时调度系列之Quartz.Net详解 第十七节:易混淆的概念(静态和非静态、拆箱和装箱) 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)