La programmation asynchrone en JavaScript sans désordre rappels
Je veux tourner asynchrone fonction de la machine synchrone.
function fetch() {
var result = 'snap!';
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function messyCallback(data){
result = data;
});
return result;
}
document.write(fetch());
Le résultat sera toujours " snap!', parce que $.getJSON
courir après fetch()
est fait.
Ma première idée était:
function fetch() {
var result = 'snap!';
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function messyCallback(data){
result = data;
});
while (true) {
if (result != 'snap!') return result;
}
}
Il ne fonctionne pas et aussi souffler le navigateur.
J'ai lu sur les générateurs et les itérateurs en JS 1.7, mais je n'ai aucune idée de comment l'appliquer à mon problème.
Cette question n'est pas vraiment à propos de jQuery. Au lieu de $.getJSON pourrait être n'importe quel autre fonctions asynchrones.
Possible (probable?) double - voir stackoverflow.com/questions/1455870/....
Jeff, je ne le pense pas. J'utilise JSONP d'appel, qui a toujours synchrone.
JSONP est seulement synchrone lorsque analysée dans le cadre du document HTML. Si elle est ajoutée à la page en utilisant le DOM, c'est asynchrone.
Oups, je voulais dire ", qui sont toujours asynchrone".
Jeff, je ne le pense pas. J'utilise JSONP d'appel, qui a toujours synchrone.
JSONP est seulement synchrone lorsque analysée dans le cadre du document HTML. Si elle est ajoutée à la page en utilisant le DOM, c'est asynchrone.
Oups, je voulais dire ", qui sont toujours asynchrone".
OriginalL'auteur NVI | 2010-02-08
Vous devez vous connecter pour publier un commentaire.
Voir cette question aussi: Stopper l'exécution de JavaScript, sans bloquer le navigateur
Faire exactement ce que vous voulez ne fonctionne pas. Vous ne pouvez pas créer de synchronousness de asynchronousness (seulement dans l'autre sens!) dans un single-threaded manifestation axée sur l'environnement. Vous devez embrasser la nature asynchrone de la langue, et de développer votre propre style cohérent autour de la manipulation des rappels afin que votre code est lisible et maintenable. Vous pourriez, par exemple, choisir de ne jamais faire aucun travail réel à l'intérieur d'un rappel de fermeture, mais il suffit d'appeler une autre fonction de haut niveau, de méthode, de clarté.
OriginalL'auteur Ben Zotto
Vous voulez faire vos propres $.getSyncJSON qui utilise $.ajax({async:false}). Voir: http://api.jquery.com/jQuery.ajax/.
Je dois vous aviser à l'encontre de ce cours d'action, cependant. Vous pouvez facilement verrouiller le navigateur à partir de toutes les entrées, en mettant à votre INTERFACE utilisateur à la merci du réseau. Mais si vous savez ce que vous faites et que vous êtes sûr de votre cas d'utilisation, d'aller pour elle.
OriginalL'auteur Plynx
Au lieu d'écrire des méthodes d'assistance, comme votre
fetch
qui retournent une valeur, leur faire accepter une autre fonction, un "récepteur", de transmettre leur résultat:Évidemment, ce n'est superflu, parce que c'est exactement comment
getJSON
fonctionne déjà, mais dans une plus réalistes exemple lefetch
fonction de processus ou de filtrer le résultat d'une certaine manière, avant de la transmettre.Puis, au lieu de:
Vous souhaitez faire:
Les générateurs peuvent être utilisés pour faire du code asynchrone beaucoup plus linéaire dans le style. Chaque fois que vous besoin d'un peu asynchrone résultat, vous auriez du rendement en fonction de la lancer, et le générateur de la reprise lorsque le résultat n'était disponible. Il y avait un peu de code de gestion en gardant le générateur va. Mais ce n'est pas beaucoup d'aide, parce que les générateurs ne sont pas la norme sur tous les navigateurs.
Si vous êtes intéressé, voici un blog sur l'utilisation de générateurs de procéder à un toilettage du code asynchrone.
oups, bon appel.
J'ai eu un jeu avec Mozilla générateurs et ils semblent excellentes. La honte qu'ils ne sont pas largement adoptée ailleurs. Voir le lien que j'ai ajouté à la fin de la réponse.
OriginalL'auteur Daniel Earwicker
Il est une extension du langage JavaScript appelé StratifiedJS. Il fonctionne dans tous les navigateurs, et il vous permet de le faire: le traitement asynchrone des problèmes en mode synchrone/linéaire, sans le gel de votre navigateur.
Vous pouvez activer Stratifié JavaScript par exemple en incluant les Oni Apollon dans votre page web, comme:
Et votre code devrait ressembler à:
Ou si vous voulez vraiment utiliser jQuery dans StratifiedJS:
Les docs sont sur http://onilabs.com/docs
OriginalL'auteur tomg
La TameJS bibliothèque est conçue pour faire face à ce problème.
Vous pouvez écrire quelque chose comme (non testé):
OriginalL'auteur Emil Sit
Le niveau inférieur $.ajax() de la fonction de jQuery a plus d'options, y compris
async: [true|false]
(la valeur par défaut est true).Néanmoins, dans la plupart des cas, vous devez suivre Ben, les conseils et le "embrasser la nature asynchrone de la langue".
Drew: Merci pour l'appel de cette. C'est vrai que JS a un petit nombre de (point de prêter à confusion) des appels synchrones, du XMLHttpRequest
get
être l'un d'entre eux.Je voulais dire
async:false
ne fonctionne pas avec JSONP appels.OriginalL'auteur Drew Wills