in JavaScript

Pyramid of Doom (1)

引子

在学Node的时候,遇到了一个关于回调的问题:

有若干个进行资源调用的函数(比如它们共享一个mongoDB的连接),要确保在它们都执行完成后,执行一个资源销毁的函数,怎么做比较好?

Node提供的是一个纯异步的执行环境,决定了至少这样的代码是行不通的:

因为:很可能在函数a或b执行完成之前,destory已经被触发。

那这样行不行:

当然行,随之而来的问题也很明显:

  • 函数互相间的侵入性太强,基本弹不上什么模块化
  • 这只是举例就两个方法a和b,执行链的扩容和回调嵌套的深度是成比例线性上升的,}}}}}}}}}}}}…太可怕了,我不保证不会有typo

回调嵌套形成的结构,被形象的称之为 “Pyramid of Doom” 🙂

JavaScript... Y U NO COROS!?

事实上, NPM上有很优秀的库可以解决这种问题, 比如:async, wind

在上述这种场景中,实际需要的是一个工具:异步调用各个函数时,能汇总各函数的完成状态,在全部完成时,统一善后。

场景

更真实的场景大概是,有若干个方法共享一个MongoDB实例连接,在执行完成后,需要断开连接:

思路1

能不能将要执行的函数构造成一个数组,写一个工具函数去迭代执行它们,并与它们协定,在执行完成前通知工具函数,工具函数负责记数以确定所有函数是否执行完成?

很容易想到事件是不是,使用EventEmitter,协定好事件,调与被调生殖隔离:

调用:

结论:丑,不满意 🙁

思路2

在进行数组迭代时,把计数器变量闭包到一个回调函数中,每一个函数执行完成时,都去回调它:

调用:

小结:貌似更丑了,而且对于实际执行的数组构造,有了更强的侵入 🙁

小结

虽然抓住了执行流汇总的本质,但上述思路有一个潜在的问题:并不是真串行,仅仅只是汇总。

也许Promise / Deferred 模式会是一个更好的方案——先到这里,我得去充电了 🙂

打赏作者
您的支持将激励我继续创作!

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

Write a Comment

Comment