Нечто похожее на jQuery когда / то: отложенное выполнение с разрывом - PullRequest
0 голосов
/ 01 марта 2012

Я ищу решение, в котором я могу запускать различные функции, но для некоторых из них требуется тайм-аут, а все последующие функции должны ждать до завершения предыдущей.Каждая функция должна быть в состоянии прервать весь процесс.

Теперь я подумал о том, чтобы поместить все функции в стек и выполнить их цикл:

function foo() {
    // bar() should wait as long the following is finished:
    setTimeout(function(){
        if ((new Date()).getSeconds() % 2) {
            alert('foo');
            // break loop through functions (bar is not called)
        }
        else {
            // start next function (bar is called)
        }
    }, 1000);
}
function bar() {
    setTimeout(function(){
        alert('bar')
    }, 1000);
}
var functions = new Array('foo', 'bar');
for (var i = 0, length = functions.length; i < length; i++) {
    window[functions[i]]();
}

Но как включить ожидание / прерывание?1006 *

Примечание: Это должно работать с 2+ функциями (количество функций можно изменять)

Примечание2: Я не хочу использовать jQuery.

Ответы [ 2 ]

2 голосов
/ 01 марта 2012

Примечание: я обновил свой ответ, см. Нижнюю часть сообщения.

Хорошо, давайте посмотрим.

Вы используете метод window[func](), поэтому вы должны иметь возможность хранить и использовать возвращаемые значения из каждой функции.

Доказательство :

function a(){
    return "value";
}

var ret_val = window['a']();
alert(ret_val);

Давайте создадим правило возврата:
Если функция возвращает true, продолжайте выполнение.
Если функция возвращает false, прервать выполнение.

function a(){
    //Do stuff
    return (condition);
}

for(i = 0; i < n; i++){
    var bReturn = window['function']();
    if(!bReturn) break;
}

Теперь давайте применим это на практике.

function a(){
    //Do stuff
    return ((new Date()).getSeconds() % 2); //Continue?
}

function b(){
    //Do stuff
    return true; //Continue?
}

function c(){
    //Do stuff
    return false; //Continue?
}

function d(){
    //Do stuff
    return true; //Continue?
}

var functions = new Array('a', 'b', 'c', 'd');

for (var i = 0; i < functions.length; i++ ) {
    var bReturn = window[functions[i]]();
    if(!bReturn) break;
}

В зависимости от того, когда вы выполняете сценарий, например, четный или неровный период времени, он будет выполнять только функцию a или выполнять функции a b & c. Между каждой функцией вы можете заниматься своими обычными делами.
Конечно, условия, вероятно, отличаются от каждой отдельной функции в вашем случае.

Вот пример JSFiddle , где вы можете увидеть его в действии.


С помощью небольшой модификации вы можете, например, сделать так, чтобы, если функция a вернула false, она пропустила следующую функцию и продолжила переход к следующей или к следующей после нее.

Изменение

for (var i = 0; i < functions.length; i++ ) {
    var bReturn = window[functions[i]]();
    if(!bReturn) break;
}

К этому

for (var i = 0; i < functions.length; i++ ) {
    var bReturn = window[functions[i]]();
    if(!bReturn) i++;
}

Будет пропускать одну функцию каждый раз, когда функция возвращает false.

Вы можете попробовать это здесь .


В дополнение к этому, если вы искали функцию ожидания, которая "приостанавливает" сценарий, вы можете использовать этот фрагмент кода .

function pausecomp(millis){
    var date = new Date();
    var curDate = null;

    do { 
        curDate = new Date(); 
    }while(curDate-date < millis);
} 

Обновление

После настройки кода теперь он работает с setTimeout.

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

Пример | Код

function next_function(index){
    if(index >= functions.length) return false;
    setTimeout(function(){
            window[functions[index+1]](index+1);
    }, 1000);
}

function a(index){
    //Do stuff
    if(((new Date()).getSeconds() % 2)) return false; //Stop?
    next_function(index);
}

function b(index){
    //Do stuff
    if(false) return false; //Stop?
    next_function(index);
}

function c(index){
    //Do stuff
    if(true) return false; //Stop?
    next_function(index);
}

function d(index){
    //Do stuff
    if(false) return false; //Stop?
    next_function(index);
}

var functions = new Array('a', 'b', 'c', 'd');

//entry point   
window[functions[0]](0);
1 голос
/ 01 марта 2012

Это именно тот сценарий, который обещает решить.В частности, тот факт, что обещания могут быть нарушены, идеально подходит для вашей ситуации, поскольку нарушенное обещание препятствует продолжению цепочки (точно так же, как выброшенное исключение в синхронном коде).библиотека обещаний , обсуждаемая на слайдах, указанных выше:

function fooAsync() {
    return Q.delay(1000).then(function () {
        if ((new Date()).getSeconds() % 2) {
            alert("foo");
            throw new Error("Can't go further!");
        }
    });
}

function barAsync() {
    return Q.delay(1000).then(function () {
        alert("bar");
    });
}

var functions = [fooAsync, barAsync];

// This code can be more elegant using Array.prototype.reduce, but whatever.
var promiseForAll = Q.resolve();
for (var i = 0; i < functions.length; ++i) {
    promiseForAll = promiseForAll.then(functions[i]);
}
// Of course in this case it simplifies to just
//     promiseForAll = fooAsync().then(barAsync);

promiseForAll.then(
    function () {
        alert("done!");
    },
    function (error) {
        alert("someone quit early!");
        // and if you care to figure out what they said, inspect error.
    }
).end();
...