Je suis en train d'écrire une fonction en Javascript (avec jQuery, si vous voulez):Comment est-ce que j'emballe des exécutions de fonctions asynchrones (basées sur le rappel) dans une fonction synchrone dans Javascript?
function fetchItem(itemId) { return /* ??? */; }
Cette fonction repose sur une seconde, la fonction prédéfinie et unmodifyable qui ressemble à ceci:
function load(callback) { /* ... */ }
Cette fonction est asynchrone. Après l'avoir appelé, il récupère n éléments via XHR, puis quand ils sont arrivés, les stocke dans le DOM, puis appelle le callback.
fetchItem
utilise un simple sélecteur jQuery (hors de propos ici) pour vérifier les DOM pour l'élément avec itemId
et demande load
si l'article est pas encore là. Rincez et répétez.
Mon problème est que je veux envelopper plusieurs appels asynchrones de load
dans ma fonction synchrone fetchItem
, qui doit retourner l'élément DOM avec itemId
après avoir fait assez load
appels.
Pseudo code, si load
était synchrone:
function fetchItem(itemId):
while not dom.contains(itemId):
load()
return dom.find(itemId)
Mes premières tentatives de le faire en Javascript, qui affiche probablement beaucoup d'idées fausses sur les fermetures de Javascript et modèle d'exécution:;)
function fetchItem(itemId) {
var match = undefined;
function finder() {
match = $(...).get(0);
if(!match) {
load(finder);
}
}
finder();
return match;
}
Évidemment, cela échoue parce que le return
est exécuté avant le premier rappel. Aussi, comme vous pouvez le voir, j'ai eu quelques problèmes pour obtenir match
revenir à fetchItem
. Est-il correctement protégé par la fermeture ici? Cela fonctionnerait-il si fetchItem était exécuté plusieurs fois en parallèle, en supposant que load
le supporte (et ne mélange pas le DOM)?
Je suis manque probablement un modèle parfaitement bien ici, mais je ne sais pas vraiment quoi google pour ...
Le rappel lui-même crée de la synchrone à partir de la routine asynchrone, n'est-ce pas?Une chose se passe après l'autre. – Orbling
@Orbling: Non, ce n'est pas le cas. Vous ne pouvez pas prédire lequel des deux appels asynchrones finit en premier (_that_ serait synchrone). – jwueller
Non, mais vous pouvez configurer votre code de sorte qu'un morceau de code donné suive un appel asynchrone, ou même après que plusieurs appels asynchrones aient eu lieu. Le seul point de doute est l'ordre de retour lorsque plusieurs appels asynchrones sont lancés. – Orbling