主要是promise,generator,async这几个。
1、promise就是改进了回调的层层嵌套,避免了回调地狱(回调的问题在于代码是横向发展的,多个异步操作强耦合,只要一个操作要修改上层下层的回调就都要修改)。
promise写成链式调用,但是链式调用也只是使得异步的几段执行更加清楚,并没什么新意。而promise的问题则在于代码冗余,原来的任务被promise包装后一眼看去全是then,原来的语义变得不清晰。
2、为了解决这个问题,就到了generator函数。generator函数就是一个封装的异步任务,
function* gen(){
var result=yield fetch(url);
console.log(result.xxx);
}
var g=gen();
var result=g.next();
result.value
.then((data)=>data.json))
.then((data)=>g.next(data))
发现generator函数和同步的写法超级像,也没有了上面的那些问题,但是它的流程管理却不太容易,即什么时候执行第一段,什么时候执行第二段(如果是异步的话需要第一段执行完(一般是promise对象的then之后)才能执行第二段)
那么后面我们有了co模块可以帮助我们自执行generator函数。也就是直接co(gen)就行。
co模块的原理是什么呢?其实跟上面的执行差不多、内部是一个递归,判断有没有执行到最后一步(判断next.done),看yield后面的promise对象执行完没有,执行完进行下一步(next调用),如下
function run(gen){
var g=gen();
function next(data){
var result=g.next(data);
if(result.done)return result.value;
result.value.then((data)=>{next(data)})
}
next();
}
3、最后就到了async函数了,简单的说它是generator函数的语法糖,把函数命名上的 * 号改成async,把yield改成await就行。但是最重要的是, async函数自带执行器,执行它非常简单,直接函数调用就可以,不需要像generator函数需要执行器(或手动调用next)执行
还有几个好处:语义化更明确、await后面不一定是promise对象(如果不是就相当于同步)、返回值是promise
发展到这基本异步就结束了,async一统天下。