[技术分享]ES7之 Async / Await 底层解密

shangjin发布于3 个月前 • 124 次阅读

大家写代码的的时候,使用async await是不是感觉很轻松呢,代码简洁明了,也没有回调地狱,那么大家想过底层是如何实现的吗。下面我们用generyator和promise模拟实现一个类似async await的函数。
思路是这样,首先我们要自定义一个generyator,然后获得它的迭代器(以下简称为迭代器),我们都知道迭代器会遍历执行generyator函数,并且返回yield的值,也就是我们需要的等待执行!接着我们只需要在合适的时候,调用迭代器的next方法即可!聪明的你一定想到了,使用promise控制迭代器调用,那么思路齐了!看到这里,很多人会有一个问题,既然generyator函数也能实现等待,我们还要用async await。个人认为async await有2个generyator函数没有的优点,第一个不需要像generyator函数控制迭代器调用,毕竟底层封装好了。第二个是语义化更强,更加简洁明了!下面上我们的代码!

image

我们来一点点来拆解上面的代码,就像我们的思路一样!我们把generyator函数变成了构造器函数,通过闭包的形式获得迭代器_iterator ,同时我们申明了一个辅助函数,用来在合适的时机调用构造函数的next方法,最下面try和catch是我们第一次调用的迭代器方法。大家注意,_iteratorRes表示每次调用迭代器返回的结果,对比上面的思路,我们希望它的value是一个promise对象,这也契合了await后面的必须是promise对象这一理论。if(_iteratorRes.done){return;}这一句代表迭代器结束,重点看下面的,我们获得了_iteratorRes的value,然后判断其value是不是在Promise原型上,如果在说明value也是一个promise,已经证明了上面这个结论!value因为是promsie对象,所以调用then执行下一次迭代,同时把上一次迭代器返回的值传入!完美的模拟了 async await底层实现!说白了,就是用promise控制generyator函数的迭代器调用。

大家可能想着如何使用,看下面那张图,一切尽在不言中!getAjax是远程请求,获得_promsie1,_promsie2的获得依赖于_promsie1,同理_promsie3的获得依赖_promsie2,于是你懂的,对照上面的方法,我们基本模拟了async await实现!

image

共收到 0 条回复