2009-09-18 7 views
7

(Cette question n'est pas vraiment limité à la langue si s'il vous plaît ne hésitez pas à soumettre une solution dans d'autres langues.)JavaScript défi chaining méthode

Je me demandais s'il serait possible d'écrire quelque chose comme ça en JavaScript :

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

Lorsque la manière traditionnelle serait d'écrire

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

Désolé si cela est une question noob: p

+0

Je pense que vous avez répondu à votre propre question ... qu'est-ce qui ne va pas avec le deuxième bloc de code? – Zoidberg

+0

@Zoidberg: Le titre est le chaînage des méthodes, donc il ne s'agit pas vraiment de le faire fonctionner, mais de le faire fonctionner en utilisant le chaînage des méthodes. – kizzx2

Répondre

37

Vous pouvez écrire facilement:

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

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

Si vous voulez aller en profondeur, je vous recommande de lire à propos currying et partial function application, ces sujets sont vraiment intéressants.

+0

Battez-moi aussi !!! – Zoidberg

+0

Insigne de type rapide. (ou était-ce prêt?) –

+0

@cemkalyoncu: Je suis une dactylo rapide, et j'utilise Vim comme édition partout :-D – CMS

0

Si vous faites OO Javascript, alors oui, vous pouvez faire un chaînage de méthode.

Certains des frameworks JavaScript populaires le font. jQuery le fait en retournant l'objet jQuery pour les fonctions qui ne retourneraient généralement pas une valeur.

2

est plutôt Enchaînement utilisé pour exécuter plusieurs méthodes sur un objet. Alors vous préférez considérer la fonction comme l'objet et définissez le délai d'attente là-bas:

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

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

Pourtant, une autre version, sans fermeture:

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

Avec un peu plus de code, vous pouvez même appeler les fonctions à plusieurs reprises:

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: Votre approche est bonne et est ce que je pense être plus complet que CMS ». Mais là encore, il a répondu correctement à la question plus vite, donc je lui ai donné la réponse correcte: p – kizzx2

0

Je viens d'écrire un little helper pour créer des API comme celui-ci d'une manière peu cohérente, peut-être que vous l'aimez.

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

L'idée est que vous construisez un constructeur fluide avec un état initial de type S en appelant une fonction d'entrée. Ensuite, chaque appel enchaîné transition vers l'état à un nouvel état. .

La valeur que vous obtenez de enchaînant un tas d'appels peut être exécuté en fonction, qui appelle la sortie pour construire une valeur de cet état et toutes les options que vous passez

    entrée
  • : * ⟶ S
  • transition: (S ⟶ *) ⟶ S
  • sortie: S ⟶ (* ⟶ *)

Par exemple

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

Alors 0, 1 sont l'entrée, les fonctions de sortie. Toutes les autres fonctions passent d'un état interne. Toutes les fonctions peuvent prendre des arguments, par exemple.opt

Nous créons une instance de notre API nouvellement conçu,

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

et appelez-

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

Jetez un oeil à la (petite) source pour voir comment cela est mis en œuvre.

ps. J'ai utilisé cette réponse pour mettre à jour les documents: D

+0

Pourquoi le vote à la baisse? – wires