Pergunta

(Esta questão não é realmente restrito à linguagem tão sinta-se livre para enviar solução em outros idiomas também.)

Eu só estava me perguntando se seria possível escrever algo como isto em JavaScript:

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

Onde a forma tradicional seria escrever

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

Desculpe se isso é uma questão de noob: p

Foi útil?

Solução

Você pode escrevê-lo facilmente:

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

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

Se você quer ir no fundo, eu recomendo que você leia sobre currying e < a href = "http://ejohn.org/blog/partial-functions-in-javascript/" rel = "noreferrer"> parcial aplicação de função , esses tópicos são realmente interessantes.

Outras dicas

No entanto, outra versão, sem fechamento:

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

Com um pouco mais de código, você pode até chamar as funções repetidamente:

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

O encadeamento é bastante usado para executar vários métodos em um objeto. Então você prefere considerar a função como o objeto e definir o tempo de espera lá:

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

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

Se você fizer OO Javascript, então sim, você pode fazer método de encadeamento.

Alguns dos frameworks JavaScript populares fazer isso. jQuery faz isso, retornando o objeto jQuery para funções que normalmente não retornam um valor.

Eu só escreveu um pouco helper para criar APIs como este de uma forma pouco consistente, talvez você como ele.

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

A idéia é que você construir um construtor fluente com algum estado inicial do tipo S chamando uma função de entrada. Em seguida, cada acorrentado transições chamam o estado para um novo estado.

O valor que você recebe de encadeamento um monte de chamadas pode ser executado como uma função, que chama saída para construir um valor daquele estado e todas as opções que se passa em.

  • entrada: * ? S
  • transição: (S ? *) ? S
  • exit: S ? (* ? *)

Por exemplo

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

Assim 0, 1 são de entrada, funções de saída. Todas as outras funções de transição de um estado interno. Todas as funções podem ter argumentos, por exemplo. opt

Nós criamos uma instância de nossa API recém trabalhada,

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

E chamá-lo

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

Tenha um olhar para o (pequeno) fonte para ver como isso é implementado.

ps. Usou esta resposta para docs atualização: D

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top