理解 JavaScript 中的延续
我正在尝试解决这个 JavaScript 闭包教程 的最后一个练习,该练习涉及延续传递。
这是练习:
定义一个名为 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));
}
I'm trying to solve the last exercise of this JavaScript Closure Tutorial which takes about Continuation Passing.
This is the exercise:
Define a function named bothC similar to seqC that takes functions fC and gC and continuations success and failure. The functions fC and gC both just take success and failure continuations. Your function bothC should call both fC and gC no matter what, but only call success if both succeeded, and failure otherwise. Don't forget, your function will never return!
This seems to be a valid answer:
var bothC = function (fC, gC, success, failure) {
fC(
function() {
gC(success, failure);
},
function() {
gC(failure, failure);
}
);
};
But why can't I just do this?
var bothC = function(fC, gC, success, failure) {
fC(gC(success, failure), gC(failure, failure));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
任何时候当你有一个函数后跟一个参数集的括号时(即使没有参数,它仍然是一个参数集),给 JS 的消息是
立即执行
。这意味着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); } );
表示“使用 a 调用fC
将调用gC(success, failure)
的函数和将调用gC(failure, failure)
作为参数的函数”仅供参考,Sussman 和 Steele表明延续和闭包或多或少是同一件事,区别基本上在于语法(这是在 70 年代末。阅读 Gabriel/Steele Lisp 的历史 第 33 页)。 JS 具有出色的闭包语法,但在我看来,当前流行语言中延续性的最佳示例是 Python
yield
语法。只是说。Any time you have a function followed by parens around an argument set (even if there are no arguments, that is still an arguments set), the message to JS is
execute immediately
. This means thatgC(success, failure)
actually runs gC and then returns whatever gC would return.fC(gC(success, failure), gC(failure, failure));
basically means, "callfC
with the return ofgC(success, failure)
andgC(failure, failure)
as parameters"In order to prevent this action and still make it callable, you need to wrap it in a
function(){}
(it can be anonymous or not). That will make it into a returnable and callable object, instead of simply as a method call.fC(function() {gC(success, failure); }, function() { gC(failure, failure); } );
means, "callfC
with a function which will callgC(success, failure)
and a function which will callgC(failure, failure)
as parameters"Just as an FYI, the Sussman and Steele showed that continuations and closures, more or less, are the same thing, the difference is basically in syntax (this was in the late '70's. Read Gabriel/Steele History Of Lisp Pg. 33). JS has great closure syntax but, in my opinion, the best example of continuation in a currently popular language is the Python
yield
syntax. Just saying.因为它调用
gC
(而不是推迟它)并将其结果传递给fC
。Because it calls
gC
(instead of defering it) and pass its result tofC
.您的代码将无法工作,因为当调用
bothC
时,它会立即调用gC
两次。 fC 应该有两个延续,这意味着它们必须是可调用函数,而不是调用函数的结果。You code won't work because it will immediately call
gC
twice whenbothC
is called.fC
is supposed to take two continuations, meaning, they have to be callable functions, not the results of calling functions.