2009-09-18 3 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); 

Извините, если это нуб вопрос: р

+0

Думаю, вы ответили на свой вопрос .... что случилось со вторым блоком кода? – Zoidberg

+0

@ Zoidberg: название - это метод цепочки, так что дело здесь не в том, чтобы заставить его работать, а заставить его работать, используя цепочку методов. – kizzx2

ответ

37

Вы можете написать легко:

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

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

Если вы хотите идти в-глубоко, я рекомендую вам прочитать о currying и partial function application, эти темы действительно интересны.

+0

Ударьте меня тоже! – Zoidberg

+0

Быстрая печать. (или это было готово?) –

+0

@cemkalyoncu: Я быстрая машинистка, и я использую Vim-подобные издания везде: -D – CMS

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

@ Кристоф: Ваш подход хороший, и я считаю, что он более всеобъемлющий, чем CMS. Но потом он снова ответил на вопрос правильно, поэтому я дал ему правильный ответ: p – kizzx2

0

Я просто написал little helper создать API, как это в некоторой степени последовательным образом, может быть, вам это нравится.

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

Идея заключается в том, что вы строите свободно строитель с некоторым начальным состоянием типа S путем вызова функции ввода. Затем каждый связанный вызов переводит состояние в новое состояние. .

Значение, которое вы получаете от цепочки кучу вызовов может быть выполнен в виде функции, которая требует выхода построить значение из этого состояния и любые варианты проезда в

  • запись: * ⟶ S
  • перехода (S ⟶ *) ⟶ 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