2017-02-04 1 views
1

Existe-t-il un moyen de l'exécuter dans cet ordre?ordre dans le déclenchement des événements et des fonctions

HTML:

<button type="button">Click!</button> 

JS:

window.addEventListener("hashchange", function() { 
    eventFunction(); 
}, false); 

document.querySelector('button').addEventListener('click', function() { 
    location.hash = "changed"; 
    otherFunction(); 
}); 

function eventFunction() { 
    console.log('first'); 
} 

function otherFunction() { 
    console.log('second'); 
} 

Voici jsFiddle: https://jsfiddle.net/texzj2uv/1/

+1

Il ne déclenchera aucun autre événement tant que le gestionnaire de 'click' n'aura pas terminé son exécution, donc non. Ce n'est pas un problème d'ordre d'événements. Votre seule option serait d'appeler 'eventFunction' et de construire un mécanisme pour éviter les appels doubles (si vous l'avez déjà appelé, ignorez' hashchanged' une fois). – Gabriel

Répondre

1

Il suffit d'appeler otherFunction de manière asynchrone:

window.addEventListener("hashchange", function() { 
 
    eventFunction(); 
 
}, false); 
 

 
document.querySelector('button').addEventListener('click', function() { 
 
    location.hash = "changed"; 
 
    setTimeout(otherFunction, 0); 
 
}); 
 

 
function eventFunction() { 
 
    console.log('first'); 
 
} 
 

 
function otherFunction() { 
 
    console.log('second'); 
 
}
<button type="button"> 
 
Click! 
 
</button>
01 Ce qui se passe quand vous appelez le location.hash = "changed";, le navigateur pousse un gestionnaire d'événements dans la file d'attente et continue avec la pile d'appels. Si vous appelez otherFunction() tout de suite, il sera sur la pile des appels et sera appelé avant tout sur la file d'attente. L'appeler comme setTimeout(otherFunction, 0) le pousse dans la file d'attente derrière le gestionnaire d'événements.

Il y a une grande vidéo expliquant javascript boucle, pile d'appel et file d'attente: Philip Roberts: What the heck is the event loop anyway? | JSConf EU 2014

+0

Cela peut fonctionner, mais vous ne devez pas tenir pour acquis que le navigateur traitera l'événement 'hashchange' avant l'intervalle de 1ms. – Gabriel

+2

Informations supplémentaires pour l'OP: Cela fonctionne parce que js eventhandlers sont poussés sur la file d'attente et sont exécutés, lorsque le fil du navigateur est vide. En appuyant sur le bouton setTimeout, vous devez également appuyer sur le second appel sur la file d'attente, ce qui rendra les deux en cours d'exécution. –

+0

@Gabriel l'intervalle de 4 ms. Jetez aussi un coup d'oeil à la technique js Qeueing –

3

utilisation setTimeout ou setImmediate pour pousser le deuxième appel à la fin de l'exécution de Qué. Le problème est que l'événement est ajouté à la fin du courant, donc vous devez soit appeler la première fonction directement, soit pousser le deuxième code à la fin du que.

document.querySelector('button').addEventListener('click', function() { 
    location.hash = "changed"; 
    setTimeout(otherFunction); 
}); 

jsFiddle: https://jsfiddle.net/texzj2uv/2/

Il est probablement mieux de gérer les choses en fonction de ce que vous essayez de faire bien. Pouvez-vous poster plus d'info un POURQUOI vous avez besoin du code exécuté dans cet ordre?

+2

@Jonasw peut réellement prendre 3 arguments. Si vous laissez le deuxième argument, qui est l'argument pour la longueur de délai minimale, il vaut par défaut 0. – TheRealMrCrowley

+0

il est pour tous les navigateurs compatibles HTML5. si vous avez besoin de prendre en charge l'un des bugs, comme probablement IE 8 et ci-dessous, le code devrait être 'setTimeout (otherFunction, 0)' – TheRealMrCrowley

+0

si c'était exact, il peut prendre 65535 arguments ... –