所谓"异步",简单说就是一个任务不是连续完成的,可以理解成该任务被人为分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段,这种不连续的执行,就叫做异步。相应地,连续的执行就叫做同步。
Promise 的写法只是回调函数的改进,使用then方法以后,异步任务的两段执行看得更清楚了,除此以外,并无新意。Promise 的最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆then,原来的语义变得很不清楚,更好的方法是:
Generator 函数:
传统的编程语言,早有异步编程的解决方案(其实是多任务的解决方案)。其中有一种叫做"协程"(coroutine),意思是多个线程互相协作,完成异步任务。协程有点像函数,又有点像线程。它的运行流程大致如下。
第一步,协程A开始执行。
第二步,协程A执行到一半,进入暂停,执行权转移到协程B。
第三步,(一段时间后)协程B交还执行权。
第四步,协程A恢复执行。
上面流程的协程A,就是异步任务,因为它分成两段(或多段)执行。
Generator 函数是 ES6 提供的一种异步编程解决方案,是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行),但属于不完全实现。Generator 函数被称为“半协程”(semi-coroutine),意思是只有 Generator 函数的调用者,才能将程序的执行权还给 Generator 函数。如果是完全执行的协程,任何函数都可以让暂停的协程继续执行。
调用 Generator 函数,返回一个遍历器对象,代表 Generator 函数的内部指针。以后,每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield表达式后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。
由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。
Generator 函数的自动执行:重点是自动执行需要一种机制,当异步操作有了结果,能够自动交回执行权。
下面是一个基于promise对象的自动执行:
Generator 函数里yield 后面要跟promise对象代码上主要就是判断done属性是否为true,是否遍历完了。否,就自调用函数,把值接着next()传下去。
async 函数:
ES2017 (ES8)标准引入了 async 函数,使得异步操作变得更加方便。
async 函数是什么?一句话,它就是 Generator 函数的语法糖。
基本用法:async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
请求并发执行:可以使用Promise.all方法
async 函数的实现原理:就是将 Generator 函数和自动执行器,包装在一个函数里。
参考文章链接:
网友评论