2012-04-16 36 views
4

我一直在学习关于continuation passing style,特别是在javascript中实现的asynchronous version,其中一个函数将另一个函数作为最终参数,并创建一个异步调用,并将返回值传递给第二个函数。延续传球与管道有何不同?

不过,我不能完全看到延续传递如何做任何事情超过重新管道(如UNIX命令行管道)或流:

replace('somestring','somepattern', filter(str, console.log)); 

VS

echo 'somestring' | replace 'somepattern' | filter | console.log 

除将管道很多,更干净。对于管道系统,似乎很明显,数据被传递,同时执行被传递给接收程序。事实上,对于管道系统,我希望数据流能够继续传递到管道中,而在CPS中,我期望有一个串行过程。

也许可以想象,如果将通信对象和更新方法与数据一起传递,而不是完整的切换和返回,CPS可以扩展为连续管道。

我错过了什么吗? CPS在一些重要的方面不同(更好?)?

要说清楚,我的意思是continuation-passing,其中一个函数将执行传递给另一个函数,而不仅仅是简单的回调。 CPS似乎暗示将函数的返回值传递给另一个函数,然后退出。

回答

3

在什么意义上说是异步?它非常类似于使用闭包的匿名回调,这是异步事件驱动编程中的常用技术,区别在于在这种情况下,回调被指定为较大结构/对象的一部分供以后使用,这意味着,当使用匿名函数时是不确定的 - 很可能是之后的原始调用返回 - 使其成为“异步”,而对于此示例,函数由调用方在内部使用,因此存在同步顺序。也许你把这两个不同的想法混为一谈?在这一点上它们看起来是一样的,将匿名函数定义为参数。

除了管道多了,干净多用管道,似乎很明显,数据传递...。”

第一项:这是角度的问题,是不是?我认为第一次看到命令行管道可能会更容易理解,但“CPS”看起来并没有太大的飞跃。这也是相当普遍的;在许多语言中“排序”内置函数会采用“比较”函数,并以几乎相同的方式使用它。

第二个:这两件事情不等于。随着管,你在做什么是这样的:

var x = replace(whatever); 
x = filter(x); 

传递一个函数的返回值到另一个并且使用与输出。而对于函数参数,filter()被替换为(),并且其输出由replace()在内部使用时被调用

+0

在异步点上:我正在考虑的实现是当回调作为异步setTimeout调用进行时,而不是同步直接函数调用。我并不是指无序。在javascript中,要做CPS,你不可避免地必须传递回调,除非产量被认为是CPS。另外,我想说的是,当CPS完成尾部呼叫时,这两件事在概念上是等价的。 – 2012-04-16 14:13:20

+0

“尾部呼叫”的结果可能影响封闭函数的结果存在显着差异。管道不是这种情况。在管道中,result()中发生了什么会影响filter()中发生的情况,但这仍然不包含CPS的可能性,其中replace会确定过滤器的作用,但过滤器也可能影响结果的作用。排序/比较就是一个例子。可能CPS不适合用来完成某些可以用程序管道x = f1()完成的工作。 X = F2(x)的。或者:使用“function(str){return'red'}”作为第二个参数来替换。 – delicateLatticeworkFever 2012-04-16 14:52:30

+0

查看它的另一种方法,pipe与CPS:x = f1(f2())复制管道,如果它表示f2()的*返回值*是arg到f1()。但那不是CPS。 – delicateLatticeworkFever 2012-04-16 15:00:20