2009-09-18 74 views
7

(這個問題是不是真的僅限於語言,所以請隨時提交其他語言的解決方案了。)JavaScript方法鏈的挑戰

我只是想知道是否有可能使用JavaScript編寫這樣的事:

// Wait 3 seconds and then say our message in an alert box 
wait(3).then(function(){alert("Hello World!");}); 

當傳統的方式是寫

// Wait 3 seconds and then say our message in an alert box 
setTimeout(function(){alert("Hello World!");}, 3000); 

很抱歉,如果這是一個noob問題:對

+0

我想你回答了你自己的問題....第二塊代碼有什麼問題? – Zoidberg 2009-09-18 17:05:44

+0

@Zoidberg:標題是方法鏈,所以這裏的東西並不是真的要讓它工作,而是讓它使用方法鏈來工作。 – kizzx2 2009-09-18 18:29:07

回答

37

你可以很容易寫:

function wait(delay) { 
    return { 
    then: function (callback) { 
     setTimeout(callback, delay*1000); 
    } 
    }; 
} 

wait(3).then(function(){alert("Hello World!");}); 

如果你想在深走,我建議你閱讀有關curryingpartial function application,這些主題是非常有趣的。

+0

也打我吧! – Zoidberg 2009-09-18 17:09:45

+0

快速的typer徽章。 (或準備好了嗎?) – 2009-09-18 17:13:00

+0

@cemkalyoncu:我是一名快速打字員,我使用Vim-like edition :-D – CMS 2009-09-18 17:14:17

0

如果你做OO的Javascript,那麼是的,你可以做方法鏈接。

一些流行的JavaScript框架可以做到這一點。 jQuery通過爲通常不會返回值的函數返回jQuery對象來做到這一點。

2

鏈接相當於用於在一個對象上執行多個方法。所以,你寧可考慮功能爲對象,並設置有超時:

Function.prototype.callAfter = function(delay) { 
    setTimeout(this, delay*1000); 
}; 

(function(){alert("Hello World!");}).callAfter(3); 
14

另一個版本,而無需關閉:

function wait(seconds) { 
    if(this instanceof wait) 
     this.delay = seconds; 
    else return new wait(seconds); 
} 

wait.prototype.then = function(callback) { 
    setTimeout(callback, this.delay * 1000); 
}; 

隨着更多的代碼,你甚至可以反覆調用的函數:

function wait(seconds) { 
    if(this instanceof wait) 
     this.delay = seconds; 
    else return new wait(seconds); 
} 

wait.prototype.then = function(callback) { 
    setTimeout(callback, this.delay * 1000); 
    return this; 
}; 

wait.prototype.wait = function(seconds) { 
    this.delay += seconds; 
    return this; 
}; 

var start = new Date; 
function alertTimeDiff() { 
    alert((new Date - start)/1000); 
} 

wait(1).then(alertTimeDiff).wait(3).then(alertTimeDiff); 
+0

@Christoph:你的方法很好,我認爲比CMS更全面。但是他又一次正確回答了這個問題,所以我給了他正確的答案:p – kizzx2 2009-09-18 18:31:13

0

我只是寫了little helper在一定程度上一致的方式來創建這樣的API,也許你喜歡它。

// > npm i mu-ffsm # install node dependency 
var mkChained = require('mu-ffsm'); 

的想法是,通過調用入口函數構造與S型的一些初始狀態一口流利的建設者。然後每個鏈接的調用將狀態轉換爲新狀態。 。

您從鏈接一串電話可以作爲一個函數,該函數調用exit構建從該狀態你在傳遞值和任何選項執行中獲得的價值

  • 項:*⟶小號
  • 過渡:(S⟶*)⟶š
  • 出口:S⟶(*⟶*)

例如

var API = mkChained({ 
    0: function(opt) {return ;/* create initial state */}, 
    then: function(s, opt) {return s; /* new state */}, 
    whut: function(s, opt) {return s; /* new state */}, 
    1: function(s, opt) {return ;/* compute final value */} 
}); 

因此0,1是進入,退出功能。所有其他功能都轉換爲內部狀態。 所有函數都可以帶參數,例如。opt

我們創造我們新制作的API的一個實例,

var call = API() // entry 
    .whut()  // transition 
    .then()  // transition 
    .whut();  // transition 

,並調用它

var result0 = call() // exit 
    , result1 = call() // exit 

看一看(小)source看到這是如何實現的。

ps。使用此答案更新文檔:D

+0

爲什麼倒票? – wires 2014-07-21 11:45:21