参考链接http://www.ruanyifeng.com/blog/2012/12/asynchronous_javascript.html
简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。比如:
回调函数:函数嵌套,将同步操作变为异步操作。 缺点:不利于代码的阅读和维护
fs.readFile('/etc/passwd', function (err, data) { if (err) throw err; console.log(data); }); f1(f2);readFile 函数的第二个参数,就是回调函数,也就是任务的第二段。等到操作系统返回了 /etc/passwd 这个文件以后,回调函数才会执行。
采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生
缺点:运行流程会变得很不清晰
存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,**其他任务可以向信号中心"订阅"(subscribe)这个信号,**从而知道什么时候自己可以开始执行。
每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。 回调函数变成了链式写法 Promise 提供 then 方法加载回调函数,catch方法捕捉执行过程中抛出的错误。 如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。
Promise****不是新的语法功能,而是一种新的写法,允许将回调函数的横向加载。
var readFile = require('fs-readfile-promise'); readFile(fileA) .then(function(data){ console.log(data.toString()); }) .then(function(){ return readFile(fileB); }) .catch(function(err) { console.log(err); }); f1().then(f2).then(f3);多个线程互相协作,完成异步任务 最大特点就是可以交出函数的执行权(即暂停执行)。 yield 命令将执行权将交给其他协程。也就是说,yield命令是异步两个阶段的分界线。 运行流程大致如下
第一步,协程A开始执行。第二步,协程A执行到一半,进入暂停,执行权转移到协程B。第三步,(一段时间后)协程B交还执行权。第四步,协程A恢复执行。上面流程的协程A,就是异步任务,因为它分成两段(或多段)执行。
next 方法返回值的 value 属性,是 Generator 函数向外输出数据;next 方法还可以接受参数,这是向 Generator 函数体内输入数据。
async 函数就是 Generator 函数的语法糖。
同 Generator 函数一样,async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
async 函数对 Generator 函数的改进,体现在以下三点: (1)内置执行器。 Generator 函数的执行必须靠执行器,所以才有了 co 函数库,而 async 函数自带执行器。也就是说,async 函数的执行,与普通函数一模一样,只要一行。
2)更好的语义。 async 和 await,比起星号和 yield,语义更清楚了。async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。
(3)更广的适用性。 co 函数库约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。