2009-09-18 13 views
7

(Questa domanda non è in realtà limitato alla lingua quindi non esitate a presentare la soluzione anche in altre lingue.)JavaScript sfida metodo concatenamento

Mi stavo chiedendo se fosse possibile scrivere qualcosa di simile in JavaScript :

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

Dove il modo tradizionale sarebbe quella di scrivere

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

Scusate se questa è una domanda niubbo: p

012.
+0

Penso che tu abbia risposto alla tua stessa domanda .... cosa c'è di sbagliato nel secondo blocco di codice? – Zoidberg

+0

@Zoidberg: Il titolo è il metodo di concatenamento, quindi la cosa qui non è proprio quella di farlo funzionare ma di farlo funzionare usando il metodo di concatenamento. – kizzx2

risposta

37

È possibile scrivere facilmente:

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

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

Se si vuole andare in profondità, vi consiglio di leggere su currying e partial function application, questi argomenti sono davvero interessanti.

+0

Picchiami anche io !!! – Zoidberg

+0

Distintivo rapido typer. (o era pronto?) –

+0

@cemkalyoncu: Sono un dattilografo veloce, e uso ovunque l'edizione simile a Vim :-D – CMS

0

Se si esegue OO Javascript, quindi sì, è possibile eseguire il concatenamento del metodo.

Alcuni dei popolari framework JavaScript fanno questo. jQuery esegue ciò restituendo l'oggetto jQuery per le funzioni che in genere non restituiscono un valore.

2

Il concatenamento è piuttosto utilizzato per eseguire più metodi su un oggetto. Così si preferisce considerare la funzione come l'oggetto e impostare il timeout c'è:

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

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

Ancora un'altra versione, senza chiusura:

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

Con un po 'più codice, si può anche chiamare le funzioni più volte:

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: il tuo approccio è buono ed è ciò che penso sia più completo di CMS ". Ma poi di nuovo ha risposto alla domanda correttamente più velocemente, così gli ho dato la risposta corretta: p – kizzx2

0

ho appena scritto un little helper per creare API come questo in un modo un po 'coerente, forse ti piace.

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

L'idea è che si costruisce un costruttore fluente con un certo stato iniziale di tipo S chiamando una funzione di ingresso. Quindi ogni chiamata concatenata trasferisce lo stato in un nuovo stato. .

Il valore si ottiene da concatenamento un gruppo di chiamate può essere eseguito come una funzione, che chiama l'uscita di costruire un valore da quello stato e le opzioni si passa

  • entrata: * ⟶ S
  • transizione: (S ⟶ *) ⟶ S
  • uscita: S ⟶ (* ⟶ *)

Ad esempio

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

Quindi 0, 1 sono le funzioni di ingresso, uscita. Tutte le altre funzioni eseguono il passaggio da uno stato interno. Tutte le funzioni possono assumere argomenti, ad es.opt

Creiamo un'istanza della nostra API di recente realizzato,

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

e chiamarlo

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

Dai un'occhiata alla la (piccola) source per vedere come questo è implementato.

ps. Ho usato questa risposta per aggiornare i documenti: D

+0

Perché il voto negativo? – wires

Problemi correlati