JS异步发展
# 回调函数
虽然最解决了异步执行的问题,但是带来了回调地狱问题:
- 调试困难:多层嵌套函数执行会让调试很困难,不利于维护与阅读;
- 耦合性太强:一旦有某一个嵌套层级有改动,就会影响整个回调的执行。
# ES6 Promise
Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和强大,就是为了解决回调函数产生的问题而产生的。特点:
- 异步操作以同步操作的流程表达出来,避免层层嵌套;
- Promise对象提供统一的接口,是控制异步操作更加容易。
缺点:Promise内部错误使用try catch捕获不到,只能使用then的第二个回调或catch来捕获。
# Generator
Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。
# 声明
与函数声明不同,在function关键字与函数名之间有一个*,以及函数体内部使用yield表达式,定义不同的内部状态。
特点:调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object),下一步,必须调用遍历器对象的next方法,使得指针指向下一个状态。yield值通过next()给了Object中的value,它实际上并没有返回值;通过next(value)中value传入的值,可以看做是yield返回值。
yield与return区别:
相同点:
- 都能返回语句后面的那个表达式的值;
- 都可以暂停函数执行。
区别:
- 一个函数可以拥有多个yield,但是只能有一个return;
- yield有位置记忆功能,return没有。
# Async/await
Async/await是Generator的语法糖,async函数相当于function *的作用,而await就相当于yield作用。
async对generator改进:
- 内置执行器,不需要next方法调用;
- 语义更清晰;
- 适用性更广,async函数的await后面,可以是promise对象,也可以是原始类型值,此时会自动转换成Promise.resolve()后的对象;
- 返回值为promise,可以后续用then方法指定下一步操作。
# 异步方案比较
- Promise的内部错误使用try catch捕获不到,then或catch来捕获;而async/await的错误可以用try catch捕获;
- Promise一旦新建就会立即执行,而async函数中的await后面promise对象会阻塞后面的代码;
- async函数会隐式返回promise;
- async函数更加简洁。
参考链接:
编辑 (opens new window)
上次更新: 2022/05/04, 21:37:45