Question

Je recherche une solution où je suis en mesure d'exécuter différentes fonctions, mais certaines d'entre elles ont besoin d'un délai d'expiration et toutes les fonctions suivantes doivent attendre jusqu'à ce que la précédente soit terminée. Chaque fonction doit être capable de briser le processus complet.

Maintenant, je pensais pousser toutes les fonctions à une pile et en faire une boucle:

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

Mais comment inclure l'attente / la pause ?!

Noter: Cela devrait fonctionner avec 2+ fonctions (la quantité de fonctions est modifiable)

Note 2: Je ne veux pas utiliser jQuery.

Était-ce utile?

La solution

Remarque: j'ai mis à jour ma réponse, voir en bas du post.

D'accord, jetons un coup d'œil.

Vous utilisez le window[func]() Méthode, vous devriez donc pouvoir stocker et utiliser les valeurs de retour de chaque fonction.

Preuve:

function a(){
    return "value";
}

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

Créons une règle de retour:
Si la fonction retourne true, continuez le flux d'exécution.
Si la fonction retourne false, briser le flux d'exécution.

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

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

Maintenant, mettons-le en pratique.

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

Selon lorsque vous exécutez le script, par exemple, une période de temps uniforme ou inégale, elle ne fera que l'exécution de la fonction a ou exécuter des fonctions a b & c. Entre chaque fonction, vous pouvez faire vos activités normales.
Bien sûr, les conditions varient probablement de chaque fonction individuelle dans votre cas.

Voici un Exemple jsfiddle où vous pouvez le voir en action.


Avec quelques petites modifications, vous pouvez par exemple, faire en sorte que si la fonction a Renvoie False, il sautera la fonction suivante et continuera à la suivante, ou à celle après cela.

En changeant

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

Pour ça

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

Le fera sauter une fonction, chaque fois qu'une fonction renvoie false.

Tu peux l'essayer ici.


Sur une note latérale, si vous cherchiez une fonction d'attente qui "fait une pause" le script, vous pourriez utiliser Ce morceau de code.

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

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

Mise à jour

Après avoir ajusté le code, il fonctionne maintenant avec setTimeout.

L'idée est que vous avez un point d'entrée, en commençant par la première fonction dans le tableau, et transmettez un paramètre d'index de l'endroit où vous êtes actuellement dans le tableau, puis l'index d'incrément avec un pour exécuter la fonction suivante.

Exemple | Code

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

Autres conseils

C'est exactement le scénario promesses résoudre. En particulier, le fait que les promesses puissent être rompues sont parfaites pour votre situation, car une promesse brisée empêche la chaîne de se poursuivre (tout comme une exception lancée dans le code synchrone).

Exemple, en utilisant le Q Bibliothèque Promise discuté dans les diapositives ci-dessus:

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();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top