2012-04-16 21 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