2010-12-03 7 views
9

Je dois écrire une fonction dans JavaScript, qui renvoie un état d'appel d'une fonction asynchrone. Cependant, l'appelant reçoit uniquement la valeur et aucune fonction de rappel ne doit être fournie. J'ai essayé quelque chose comme:Comment bloquer des fonctions asynchrones en JavaScript

function getState() { 
    var ret = null; 
    asyncCall("request", 
     function() { ret = "foo"; } // callback 
    ); 
    while (ret === null) 
     ; // block on the asynchronous call 
    return ret; 
} 

Cependant, la boucle ne va jamais finir ...

Toutes les idées? Je vous remercie.

+2

Pourquoi voulez-vous bloquer l'appel asynchrone en premier lieu? Faire cela n'a aucun sens. – Tomalak

+1

@Tomolak: parce que c'est un appel fourni par Firefox et je ne peux pas le changer. Cela devrait prendre au plus quelques millisecondes, je ne veux pas refactoriser tout mon code juste à cause de ça. –

+0

Pouvez-vous publier la fonction qui appelle 'getState()'? – Tomalak

Répondre

8

Je pense que vous cherchez StratifiedJS, http://stratifiedjs.org Il vous permet de « orchestrer » votre code async exactement comme vous l'avez écrit, méfiez-vous qu'il « écrit » comme code synchrone , il ne bloquera pas le reste de votre application. Vous pouvez l'utiliser n'importe où en chargeant la bibliothèque apollo js.

Voici comment cela ressemblerait à Stratified JavaScript:

function getState() { 
    waitfor (var ret) { 
    // block on the asynchronous call 
    asyncCall("request", resume); 
    } 
    return ret; 
} 

Bien sûr, il existe des modules/bibliothèques qui serait tout simplement la faire ressembler à ceci: http://onilabs.com/modules#http

function getState() { 
    return http.get("request"); 
} 
+0

Bien que cela repose sur un analyseur externe, il semble que la meilleure solution ici. –

+0

C'est le cas. Mais dans le grand schéma, cela n'ajoute pas beaucoup de frais généraux. – tomg

0

Pourquoi ne pas simplement:

asyncCall("request", function() { 
    // here you can inspect the state 
}); 

Quel est le point de la fonction enveloppe?

Les fonctions asynchrones fonctionnent de cette manière. Si vous voulez bloquer l'exécution, utilisez un appel synchrone:

var state = syncCall("request"); 
+0

C'est quelque chose comme une bibliothèque puisque je travaille sur plusieurs plateformes. Et le reste du code doit attendre cette information spéciale. Aucune substitution synchrone n'est fournie. –

+0

@ryanli Ensuite, placez le reste du code dans le rappel. –

+1

@ Šime: Donc vous voulez dire que les appels asynchrones pourraient infecter tous les autres codes qui l'appellent? Je veux juste savoir s'il y a un moyen de bloquer ces appels asynchrones. –

1

Le mieux serait de mettre la logique que vous voulez avoir appelé dans la fonction de rappel. Y a-t-il une raison pour laquelle vous ne pouvez pas faire cela?

Vous pouvez utiliser setInterval pour vérifier le résultat, mais cela nécessite une fonction de rappel aussi ...

+0

J'écris une extension, pas un document JavaScript normal. La partie restante de la fonction repose sur cet état, et la seule chose fournie est une fonction asynchrone. –

1

À moins d'avoir mal compris votre question, vous pouvez regarder l'événement ajaxStop() de jQuery - http://api.jquery.com/ajaxstop. Cela bloque jusqu'à ce que tous les appels ajax sont terminés. Cela nécessite évidemment que tous vos appels asynchrones soient effectués via jQuery.

$(document).ajaxStop(function() { 
    // do your "ajax dependent" stuff here 
}); 
Questions connexes