2009-09-18 12 views
7

(To pytanie nie jest tak naprawdę ogranicza się do języka, więc prosimy o przedstawienie rozwiązania w innych językach też.)JavaScript metoda łańcuchowym wyzwanie

Zastanawiam się, czy byłoby możliwe, aby napisać coś takiego w JavaScript :

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

Gdzie tradycyjny sposób byłoby napisać

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

Przepraszam, jeśli jest to pytanie noobem: p

+0

Myślę, że odpowiedziałeś na własne pytanie .... co jest nie tak z drugim blokiem kodu? – Zoidberg

+0

@Zoidberg: Tytuł jest łańcuchem metod, więc nie chodzi o to, żeby to działało, ale żeby działało, używając metody łańcuchowej. – kizzx2

Odpowiedz

37

Można ją łatwo napisać:

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

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

Jeśli chcesz iść w głębokich, polecam przeczytać o currying i partial function application te tematy są bardzo interesujące.

+0

Pokonaj mnie też !!! – Zoidberg

+0

Znaczek Fast typer. (czy było to gotowe?) –

+0

@cemkalyoncu: Jestem szybką maszynistką i używam wszędzie wersji Vima :-D – CMS

0

Jeśli zrobisz OO Javascript, to możesz, możesz użyć metody łańcuchowej.

Umożliwia to kilka popularnych frameworków JavaScript. jQuery robi to, zwracając obiekt jQuery dla funkcji, które zwykle nie zwracają wartości.

2

Łańcuchowanie jest raczej używane do wykonywania wielu metod na jednym obiekcie. Tak czy raczej rozważyć funkcję jako obiekt i ustawić limit czasu tam:

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

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

Jeszcze inną wersję, bez zamknięcia:

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

Z trochę więcej kodu, można nawet nazwać wielokrotnie funkcje:

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: Twoje podejście jest dobre i uważam, że jest bardziej wszechstronne niż CMS ". Ale potem znowu odpowiedział na pytanie poprawnie szybciej, więc podałem poprawną odpowiedź: p – kizzx2

0

właśnie napisał little helper do tworzenia interfejsów API, takich jak ten w dość spójny sposób, może Ci się spodoba.

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

Chodzi o to, że skonstruowanie biegle konstruktora z pewnego stanu początkowego typu S wywołując funkcję wejścia. Następnie każde połączenie łańcuchowe powoduje przejście stanu do nowego stanu. .

Wartość można uzyskać z łańcuchowym kilka połączeń może być realizowana jako funkcja, która wzywa zjazd do skonstruowania wartości z tego stanu i wszelkie opcje, które przechodzą w

  • wpis: * ⟶ S
  • przejście (S ⟶ *) ⟶ S
  • wyjście S ⟶ (* ⟶ *)

Przykładowo

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

Tak 0, to wejścia, funkcje wyjścia. Wszystkie pozostałe funkcje zmieniają stan wewnętrzny. Wszystkie funkcje mogą przyjmować argumenty, np.opt

Tworzymy instancję nowo spreparowanych API

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

i nazwać

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

Prosze spojrzeć na (mały) source aby zobaczyć, jak to jest realizowane.

ps. Użyłem tej odpowiedzi, aby zaktualizować dokumenty: D

+0

Dlaczego głosowanie w dół? – wires

Powiązane problemy