# JavaScript 异步模式

# Callback

  • 控制反转(inversion of control)
  • 难以理解 (回调地狱)

# thunk

thunk的出现能够保证抽离时间,让异步代码的逻辑变的简单

  • 同步thunk
  • 异步thunk

thunk 的本质其实是使用闭包来管理状态

虽然异步thunk抽离出时间后,我们的代码稍微更好理解了,但是回调的另外一个问题 — 依赖反转, 通过 thunk 却难以克服。如果用人话来说「依赖反转」,其实这是一种信任问题,回调函数的调用其实是受外界控制的, 其会不会被调用,会被调用几次都不能完全受我们控制。为了解决这个问题,出现了Promise

# Promise

  • 为一个未来值提供了占位符,消除时间的影响;
  • 事件监听器,监听 then 时间;
  • 提供了一种以可靠的方式管理我们的回调;

Promise直观的感受就是只用链式调用then简化了复杂的回调,但本质上是使用了一种约定(Promise)去保障了then后面的函数只会执行一次。 普通的 callback 实际上是第三方直接调用我们的函数,这个第三方不一定是完全可信的,我们的回调函数可能会被调用,也可能不会调用, 还可能会调用多次。Promise 则将代码的执行控制在我们自己手里,要么成功要么失败,then后面的函数只会执行一次(控制在自己的手里)。

Promise问题

  • 无法终止
  • Error的处理和捕获

# Generator

特点:

  • 函数可暂停和继续;
  • 可返回多个值给外部;
  • 在继续的时候,外面也可以再传入值;
  • 通过 Generator 写的异步代码看起来就像是同步的;

Generator问题不能自动的运行,需要自己的手动的调用next(),这个方法在任何地方都可能被调用。因此又出现了在 callback 中出现过的「控制反转」问题。 我们完全不知道谁会在什么地方调用.next(),结合 Promise 我们可以比较轻松的解决「控制反转」的问题, 一些人把 Promise + Generator 当作是异步最好的解决方案之一

  • Promise 用以解决控制反转问题;
  • Generator 则让我们的异步代码看起来像是同步的,非常容易书写和理解;

具体来说,我们可以在 Promise 中调用 .next(),Promise 机制保证了.next() 的调用是受控制的。

问题: 需要自己额外封装 runGenerator 函数。

# Async Await

通常情况下,Async/Await已经一种相对完美的的异步解决方案

问题

  • await 关键字只能结合 Promise 控制异步;
  • 无法在外界取消一个正在运行中的async函数;

# Async generator*

ES2018

# 参考

拆解 JavaScript 中的异步模式 (opens new window)

陕ICP备20004732号-3