返回介绍

第一部分 类型和语法

第二部分 异步和性能

2.1 continuation

发布于 2023-05-24 16:38:21 字数 935 浏览 0 评论 0 收藏 0

让我们回到第 1 章中给出的异步回调的例子,为了突出重点,以下稍作了修改:

// A
ajax( "..", function(..){
  // C
} );
// B

// A 和 // B 表示程序的前半部分(也就是现在 的部分),而 // C 标识了程序的后半部分(也就是将来 的部分)。前半部分立刻执行,然后是一段时间不确定的停顿。在未来的某个时刻,如果 Ajax 调用完成,程序就会从停下的位置继续执行后半部分。

换句话说,回调函数包裹或者说封装了程序的延续(continuation)。

让我们进一步简化这段代码:

// A
setTimeout( function(){
  // C
}, 1000 );
// B

请在这里稍作停留,思考一下你自己会如何(向对 JavaScript 运作机制不甚了解的某位人士)描述这段程序的运行方式。然后试着把你的描述大声说出来。这有助于你理解我接下来要展示的要点。

大多数人刚才可能想到或说出的内容会类似于“执行 A,然后设定一个延时等待 1000 毫秒,到时后马上执行 C”。你的描述准确度如何呢?

也可能进一步修改为“执行 A,设定延时 1000 毫秒,然后执行 B,然后定时到时后执行 C”。这比第一个版本要更精确一些。你能指出其中的区别吗?

尽管第二个版本更精确一些,但是在匹配大脑对这段代码的理解和代码对于 JavaScript 引擎的意义方面,两个版本对这段代码的解释都有不足。这种不匹配既微妙又显著,也正是理解回调作为异步表达和管理方式的缺陷的关键所在。

一旦我们以回调函数的形式引入了单个 continuation(或者几十个,就像很多程序所做的那样!),我们就容许了大脑工作方式和代码执行方式的分歧。一旦这两者出现分歧(这远不是这种分歧出现的唯一情况,我想你明白这一点!),我们就得面对这样一个无法逆转的事实:代码变得更加难以理解、追踪、调试和维护。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文