Skip to content

JS 异步编程

要点速览

shell
# JS 异步发展的四个阶段
- 第一阶段:回调函数(缺点:回调地狱,可读性差、可维护性差)
- 第二阶段:Promise(解决回调地狱,链式调用,三种状态不可逆)
- 第三阶段:Generator(函数暂停/恢复,配合yield,可实现异步流程控制)
- 第四阶段:async/await(Promise的语法糖,同步写法实现异步,可读性最优)

拓展

shell
# 回调函数 Callback
多层嵌套造成回调地狱问题

# Promise 所有方法
链式调用,解决回调函数问题
三种状态:pending、fulfilled、rejected;状态一旦改变,不可逆
Promise 实例方法:then、catch、finally
Promise 静态方法:resolve、reject、all、allSettled、race、any
# Promise 静态方法
resolve 快速返回 Promise 成功结果
reject 快速返回 Promise 失败结果
all 每一个都成功才会成功,任何一个失败则失败
allSettled 无论成功和失败,全部执行完毕后返回结果集
race 最快的返回,返回的是成功则成功,返回的是失败则失败
any 首个成功则成功,全部失败才失败
# Promise 常见问题
Promise 穿透:then 传入非函数参数时,发生值穿透,上一步结果直接透传下一步,当前回调被忽略。
then 异步原因:Promise 状态变更同步完成,但 then 回调规定必须异步微任务执行,统一异步规范、避免同步阻塞、保证执行顺序。
错误捕获:reject then 内部 throw 都会转为失败状态;错误向后穿透直到第一个 catch;未捕获会触发未处理拒绝警告;finally 不拦截错误。


# Generator 生成器函数
可以暂停执行和恢复执行,并在每次暂停时返回值。
声明:function*
暂停 yield 关键字:暂停函数执行,返回一个值给外部,可以接收外部传入的值(通过 next 方法)
执行 next() 方法:恢复函数执行,返回 { value: any, done: boolean } 对象
异常处理:在函数内部使用 try catch
提前终止:与 next() 方法同级的 return() 方法,提前终止 Generator
# Generator 使用场景
实现迭代器:Symbol.iterator
异步流程控制(模拟 async/await):定义一个自执行函数,传入 Generator 函数,让其自动执行下一个异步

# async/await
async 函数总是返回 Promise,如果 return 的值不是 Promise 则会包装成 Promise
await async 内部等待后面的函数执行完,返回执行后的结果(阻塞当前函数,不阻塞全局)
错误处理:try/catch

# 并发执行
串行:async、await
并行:Promise.all()、Promise.allSettled()

# 循环中的 await
顺序串行:for of / for await of