ES7的async和await,目前最为简略的异步解决方案
2017-03-30 18:57
801 查看
随着js的发展,在解决回调地狱问题的方案上,解决方案逐渐更新,有promise、generator和现在的async都是比较常见的;
1.Promise
这个解决方案就是把异步用同步的方式写出来,一步一步的
这就是promise的异步解决方案看起来还是很简单的,其实只是以你为逻辑简单;
2.Generator
Generator函数是个异步管理器,这里要提到一个协程的概念,先不用管协程是什么鬼,先来介绍一下
以上代码中,当函数执行的时候分一下步骤:
a.开始执行代码A;
b.代码A执行到一半,遇到yield命令,暂停执行,开始执行,执行权交给
c.当yield函数执行完之后,交还执行权;
d.继续执行
在这个过程中,代码段A被分成两段执行,代码段A叫做协程A,
再来举个例子:
a.调用Generator函数并不会像其他普通函数一样返回函数值,它会返回一个内部指针——g;
b.调用内部指针中的
c.上面代码中,第一次调用
d.当然next方法也是可以传值的,如下:
这时第二个
对了这里在补一句,从上可以看出Generator函数是需要手动执行的,那么有没有可以让其自执行的办法呢,有~
co模块小工具可以让Generator函数自执行,只要把其当参数传进co中;
3.async函数
这个es7草案,说实话也是最简单的异步解决方案,问其原理,其实是Generator函数的语法糖;
a:
执行结果是:
先打印出
是不是跟Generator函数很相似,
b.当然了,也是可以获取到返回值的:
这样,5s后打印出来的就是
c.当然,也可以捕获错误:
这里
d.当然了,这里也是可以循环多执行await的
这里指出非常重要的一点,await命令必须要在async函数的上下文中,也就是说当await命令所在的环境中this的指向不是async的时候,会报错!
所以这里要用for循环,for…of循环,不能用map,forEach方法等;
1.Promise
这个解决方案就是把异步用同步的方式写出来,一步一步的
.then()方法,前一个.then()执行完之后,继续执行下一个
.then();
function timeout (time) { return new Promise((res, rej)=>{ setTimeout(()=>{ res('this is a returnDate'); },time) }) }; time(5000) .then((data)=>{console.log(data)}) .then(()=>{console.log('end')}) ...
这就是promise的异步解决方案看起来还是很简单的,其实只是以你为逻辑简单;
2.Generator
Generator函数是个异步管理器,这里要提到一个协程的概念,先不用管协程是什么鬼,先来介绍一下
yield命令,它是Generator函数中的分水岭,在函数内部起执行权转义的功能,什么是执行权?好吧,这就是在Generator函数内部遇到yield命令,那么就不往下执行了,就把执行权交出来给别的函数,等别的函数执行之后返回结果了,在返还执行权,继续向下执行Generator函数的语句;
function generator () { // 代码A; var f = yield readFile(fileA); // 代码A; }
以上代码中,当函数执行的时候分一下步骤:
a.开始执行代码A;
b.代码A执行到一半,遇到yield命令,暂停执行,开始执行,执行权交给
yield命令后面的函数;
c.当yield函数执行完之后,交还执行权;
d.继续执行
yield命令下面的代码A;
在这个过程中,代码段A被分成两段执行,代码段A叫做协程A,
readFile()函数叫做协程B,协程A是异步的;
再来举个例子:
function* gen(x){ var y = yield x+2; return y } var g = gen(1); g.next() // { value:3, done:false } g.next() // { value:undefined, done:ture }
a.调用Generator函数并不会像其他普通函数一样返回函数值,它会返回一个内部指针——g;
b.调用内部指针中的
next方法,会移动指针分配执行权去手动执行函数;返回结果会是一个对象,
value字段对应运算值,
done字段是布尔类型,说明函数是否执行完;
c.上面代码中,第一次调用
next方法,函数执行到
x+2,值返回给value属性;第二次调用
next方法,执行代码是
return y,这时y并没有值,只是定义了,所以第二次vlaue的值是
undefined;
d.当然next方法也是可以传值的,如下:
var g = gen(1); g.next() // { value:3, done:false } g.next(2) // { value:2, done:ture }
这时第二个
next方法带有参数2,这个参数会传到Generator函数内部,作为上个协程任务的返回结果被函数体内的变量y接收,因此value的值是2;
对了这里在补一句,从上可以看出Generator函数是需要手动执行的,那么有没有可以让其自执行的办法呢,有~
co模块小工具可以让Generator函数自执行,只要把其当参数传进co中;
var co = require('co'); co(gen);
3.async函数
这个es7草案,说实话也是最简单的异步解决方案,问其原理,其实是Generator函数的语法糖;
a:
function timeout (time) { return new Promise((res, rej)=>{ setTimeout(()=>{ res(); },time) }) } let start = async function () { console.log('start'); let data = await timeout(5000); console.log('end'); }
执行结果是:
先打印出
start,然后转为
timeout函数执行,执行时间为5s,之后返回打印出
end;
是不是跟Generator函数很相似,
await跟
yield命令作用一样~
b.当然了,也是可以获取到返回值的:
function timeout (time) { return new Promise((res, rej)=>{ setTimeout(()=>{ res('this is a returnDate'); },time) }) } let start = async function () { console.log('start'); let data = await timeout(5000); console.log(data); }
这样,5s后打印出来的就是
this is a returnDate;
c.当然,也可以捕获错误:
function timeout (time) { return new Promise((res, rej)=>{ setTimeout(()=>{ rej('this is an err'); },time) }) } let start = async function () { console.log('start'); try { let data = await timeout(5000); console.log(data); } catch (err) { console.log(err); } }
这里
timeout函数返回一个错误,那么被
try...catch...语句中的
catch捕获,则不执行
try中的代码,直接执行
catch中的代码,打印出错误;
d.当然了,这里也是可以循环多执行await的
function timeout (time) { return new Promise((res, rej)=>{ setTimeout(()=>{ rej('this is an err'); },time) }) } let start = async function () { for(let i=0; i<=10; i++) { console.log(`这是第${i}次等待`); await timeout(5000); } }
这里指出非常重要的一点,await命令必须要在async函数的上下文中,也就是说当await命令所在的环境中this的指向不是async的时候,会报错!
所以这里要用for循环,for…of循环,不能用map,forEach方法等;
相关文章推荐
- 异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- 体验异步的终极解决方案-ES7的Async/Await
- ES7——异步解决方案Async/Await
- es7异步神器async-await
- ES7的Async/Await 异步
- 「大概可能也许是」目前最好的 JavaScript 异步方案 async/await
- 前端的异步解决方案之Promise和Await-Async
- 终极异步解决方案async,await以及异步并发处理方案
- ES7之async/await 同步还是异步
- 解决js异步问题的方法--async和await(ES7)