理解JavaScript中的连续体

理解JavaScript中的连续体,javascript,continuations,Javascript,Continuations,我想解决最后一个关于连续传球的练习 以下是练习: 定义一个名为bothC的函数,类似于seqC,它接受函数fC和gC以及continuations success和failure。功能fC和gC都只是成功和失败的延续。无论发生什么情况,您的函数bothC都应该同时调用fC和gC,但只有在两者都成功时才调用success,否则调用failure。别忘了,你的函数永远不会返回 这似乎是一个正确的答案: var bothC = function (fC, gC, success, failure) {

我想解决最后一个关于连续传球的练习

以下是练习:

定义一个名为bothC的函数,类似于seqC,它接受函数fC和gC以及continuations success和failure。功能fC和gC都只是成功和失败的延续。无论发生什么情况,您的函数bothC都应该同时调用fC和gC,但只有在两者都成功时才调用success,否则调用failure。别忘了,你的函数永远不会返回

这似乎是一个正确的答案:

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));
}

因为它调用
gC
(而不是延迟它)并将其结果传递给
fC
,所以代码不会工作,因为调用
bothC
时,它会立即调用
gC
两次
fC
应该有两个连续,这意味着它们必须是可调用的函数,而不是调用函数的结果。

任何时候在参数集周围有一个函数后跟参数(即使没有参数,这仍然是一个参数集),发送给JS的消息是
立即执行
。这意味着
gC(成功,失败)
实际运行gC,然后返回gC将返回的任何内容<代码>fC(gC(成功,失败),gC(失败,失败))的基本意思是,“调用
fC
,返回
gC(成功,失败)
gC(失败,失败)
作为参数”

为了防止此操作并使其仍然可调用,您需要将其包装在
函数(){}
中(它可以是匿名的,也可以不是匿名的)。这将使它成为一个可返回和可调用的对象,而不仅仅是一个方法调用<代码>fC(函数(){gC(成功,失败);},函数(){gC(失败,失败);})表示“调用
fC
,函数将调用
gC(成功,失败)
,函数将调用
gC(失败,失败)
作为参数”



仅供参考,Sussman和Steele证明了连续体和闭包或多或少是一回事,区别基本上在于语法(这是在70年代后期,阅读Gabriel/Steele第33页)。JS有很好的闭包语法,但在我看来,当前流行语言中延续的最好例子是Python
yield
语法。只是说说而已。

很有趣,现在需要阅读教程……不同意python有更好的语法。如果python函数中有一个yield语句,则不能重构该语句来调用其他函数(推迟对yield的调用)。一旦你有了收益,这个函数就被特别标记为生成器。如果您希望维护一个依赖于continuations的系统,这一点很重要(我编写了一个模拟器,并且非常想将yield语句重构为两个不同的函数)。我希望看到python语法采用像call/cc这样强大的东西。当然,在与JS语法进行比较时需要考虑一些问题。@ccoakley好吧,我喜欢这个,因为它是实际延续的最清晰的例子——返回函数作为以后可以继续的东西,而不是返回可调用对象的闭包。是的,这一点我不能不同意。你还允许自己用“最好的例子……用当前流行的语言”来表达自己的观点。但仅仅因为没有人做得更好并不意味着我必须喜欢它!此外,我已经习惯了javascript语法:)唉。。。赞成。。。很多时候我们都是这样的。。。总有一天,最美丽的语言将被创造出来,我们都认为它是美妙的。(不幸的是那天)