# JavaScript 异步解决方案

  • 什么是异步?

上一个任务被执行时,不会等待任务执行结束就去执行下一任务,等上一个任务执行完成后,将执行其返回的回调函数,这是异步操作

  • 为什么用异步?

JS 是单线程的,因此必须等待上一个任务完成后,才能执行后一个任务。当一个任务比较耗时就会影响整个程序的执行,异步就是为了解决这种问题。

# 回调函数 callback

将回调函数作为实参传入另一个函数,并在函数内部被调用,用来完成某些任务。
如:setTimeout、ajax请求、readFile等

缺点:回调地狱,代码结构混乱,不易维护

# 事件发布订阅

利用事件绑定,对某些任务进行监听,并根据变化执行相应任务。
即:观察者模式;
如:Node 的 events、DOM 的事件绑定;

优点:时间对象上的解耦
缺点:消耗内存,过度使用会难易维护

# Promise

Promise 是 ES6 提出的异步编程的一种解决方案

详见:Promise

优点:解决了回调地狱问题,将异步操作以同步操作的流程进行表达
缺点:无法取消 promise。如果不设置回调函数,Promise 内部会抛出错误,不会反映到外部。
多个 Promise 连续执行时,链式调用 .then 会显得很臃肿

# Generator

Generator 是 ES6 提出的另一种异步编程的解决方案。
需要在函数之前加上一个 * 符号,函数内部使用 yield 语句。
Generator 函数会返回一个遍历器,可以进行遍历操作 .next() 执行每个中断点 yield

优点:没有 Promise 的一堆 then(),异步操作更像同步
缺点:不是自动执行异步操作,需要手动执行多个 .next() 方法,需要配合 Thunk 函数或 Co 模块实现自动执行;
根据 done 属性判断是否执行完成;

# async/await

async/await 是 ES7 引入的异步解决方案,可以理解为 Generator 的语法糖,async 等同于 Generator 和 Co 模块的封装,async 函数返回一个 Promise。

优点:内置执行器,比 Generator 操作更简单。返回值为 Promise 对象,可以用 then 指定下一步操作。
代码更整洁,可以捕获同步和异步的错误。