【问题标题】:Understanding continuations in JavaScript理解 JavaScript 中的延续
【发布时间】:2011-10-22 13:06:05
【问题描述】:

我正在尝试解决这个 JavaScript Closure Tutorial 的最后一个练习,它需要继续传递。

这是练习:

定义一个名为 bothC 的函数,类似于 seqC,它采用函数 fC 和 gC 并继续成功和失败。函数 fC 和 gC 都只需要成功和失败的延续。无论如何,您的函数 bothC 都应该调用 fC 和 gC ,但只有在两者都成功时才调用成功,否则调用失败。别忘了,你的函数永远不会返回!

这似乎是一个有效的答案:

var bothC = function (fC, gC, success, failure) {
    fC(
      function() {
        gC(success, failure);  
      },
      function() {
        gC(failure, failure);    
      }
    );
};

但是为什么我不能这样做呢?

var bothC = function(fC, gC, success, failure) {
  fC(gC(success, failure), gC(failure, failure));
}

【问题讨论】:

  • 有趣,现在需要阅读教程...

标签: javascript continuations


【解决方案1】:

任何时候你有一个函数后跟一个参数集的括号(即使没有参数,它仍然是一个参数集),给 JS 的消息是execute immediately。这意味着gC(success, failure) 实际运行 gC,然后返回 gC 将返回的任何内容。 fC(gC(success, failure), gC(failure, failure)); 基本上意味着,“调用fC 并返回gC(success, failure)gC(failure, failure) 作为参数”

为了防止此操作并使其仍可调用,您需要将其包装在 function(){} 中(可以是匿名的,也可以不是匿名的)。这将使它成为一个可返回和可调用的对象,而不是简单地作为方法调用。 fC(function() {gC(success, failure); }, function() { gC(failure, failure); } ); 的意思是,“调用fC 的函数将调用gC(success, failure) 和调用gC(failure, failure) 作为参数的函数”


作为仅供参考,Sussman 和 Steele 表明,延续和闭包或多或少是同一件事,区别基本上在于语法(这是在 70 年代后期。阅读 Gabriel/Steele History Of Lisp Pg . 33). JS 有很好的闭包语法,但在我看来,当前流行语言中延续的最佳示例是 Python yield 语法。只是说说而已。

【讨论】:

  • 不同意 python 具有更好的语法。如果你在 python 函数中有一个 yield 语句,你不能重构它来调用其他函数(推迟对 yield 的调用)。一旦你有了 yield,这个函数就会被特别标记为一个生成器。如果您希望维护一个依赖于延续的系统,这一点很重要(我编写了一个模拟器,并且真的想将我的 yield 语句重构为两个不同的函数)。我很想看到 python 的语法采用像 call/cc 这样强大的东西。与 JS 语法相比,当然要考虑一些事情。
  • @ccoakley 好吧,我喜欢那个,因为它是实际延续的最清楚的例子——将函数作为可以在以后继续的东西返回,而不是返回可调用对象的闭包。
  • 是的,不能不同意。您还允许自己使用“当前流行语言的最佳示例……”。但仅仅因为没有人做得更好并不意味着我必须喜欢它!此外,我习惯了 javascript 语法:)
  • 叹息......是的......我们经常有这样的standards issues......总有一天,我们都同意的最美丽的语言将是美妙的。 (那天很遗憾has passed and predates the modern computer
【解决方案2】:

因为它调用gC(而不是推迟它)并将其结果传递给fC

【讨论】:

    【解决方案3】:

    您的代码将无法工作,因为它会在调用 bothC 时立即调用两次 gCfC 应该有两个延续,意思是,它们必须是可调用函数,而不是调用函数的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-15
      • 2015-06-10
      • 1970-01-01
      • 2012-02-14
      • 2012-01-17
      • 2017-07-15
      • 1970-01-01
      相关资源
      最近更新 更多