顺序与异步
回调是编写和处理 JavaScript 程序异步逻辑的最常用 方式。确实,回调是这门语言中最基础的异步模式
所以,如果说同步的大脑计划能够很好地映射到同步代码语句,那么我们的大脑在规划异 步代码方面又是怎样的呢?
答案是代码(通过回调)表达异步的方式并不能很好地映射到同步的大脑计划行为。
嵌套回调与链式回调
一种典型的回调地狱:
1 | listen( "click", function handler(evt){ |
复杂的回调,对于程序的调试和追踪代理来很高的复杂度。
这就是回调方式最主要的缺陷:对于它们在代码中表达异步的方式,我们的大脑 需要努力才能同步得上。
控制反转:
也就是把自己程序一部分的执行控制交给某 个第三方。在你的代码和第三方工具(一组你希望有人维护的东西)之间有一份并没有明 确表达的契约。
利用代码的执行依赖于,ajax(..)返回的结果。
省点回调
为了更优雅地处理错误,有些 API 设计提供了分离回调
1 | function success(data) { |
S6 Promise API使用的就是这种分离回调设计。
还有一种常见的回调模式叫作“error-first 风格”(node风格),第一个参数保留用作错误对象,如果成功,这个参数会被清空或者置假(后面的参数就是成功数据)。
1 | function response(err,data) { // 出错? |
小结
第一,大脑对于事情的计划方式是线性的、阻塞的、单线程的语义,但是回调表达异步流 程的方式是非线性的、非顺序的,这使得正确推导这样的代码难度很大。难于理解的代码 是坏代码,会导致坏 bug。
第二,也是更重要的一点,回调会受到控制反转的影响,因为回调暗中把控制权交给第三 方(通常是不受你控制的第三方工具!)来调用你代码中的 continuation。这种控制转移导 致一系列麻烦的信任问题,比如回调被调用的次数是否会超出预期。