6
votes

Est-il possible d'obtenir une fenêtre de navigateur pour mettre à jour lorsqu'il est dans une boucle JavaScript?

J'ai un appel Ajax qui doit actuellement être synchrone. Toutefois, alors que cet appel AJAX est exécuté, l'interface du navigateur gèle jusqu'à ce que l'appel renvoie. En cas de délai d'attente, cela peut geler le navigateur pour un période significative . < P> Y a-t-il un moyen d'obtenir le navigateur (n'importe quel navigateur) pour actualiser l'interface utilisateur, mais n'exécuter aucun JavaScript? Idéalement, ce serait une commande comme window.update () , qui permettrait à l'interface utilisateur thread thread rafraîchir.

Si cela serait possible, je pourrais remplacer l'appel Ajax synchrone avec quelque chose comme: xxx

la raison que je ne peux pas utiliser SetTimeout ou reprendre une fonction dans le rappel, est-ce que le flux d'exécution ne peut pas Soyez interrompu: (Il y a beaucoup trop de variables d'état qui dépendent tous les uns sur les autres, et le flux long_function () devrait être repris en quelque sorte): xxx


2 commentaires

Pourquoi l'appel doit-il être synchrone?


Pouvez-vous publier tout le code d'appel? Cela peut probablement être simplifié et utiliser les fonctions XHR pour prendre en charge ce dont vous avez besoin (à moins que JQuery ne soit une option, alors encore plus propre). Si aucune option n'est ni une option, je vous demande de renommer la fonction à do_sync_jax_call ();


4 Réponses :


0
votes

Prenez le reste de l'appel et mettez-le dans le rappel appelé lorsque le résultat revient. Je doute sérieusement que cela serait complètement impossible pour vous de faire. Toute logique que vous devez placer dans l'appel peut être dupliquée dans le rappel


0 commentaires

0
votes

Ajax Ajax Asynchrone Fetch puis Settimeout et faire le travail de traitement en morceaux (déclenchés par le rappel)


0 commentaires

3
votes

Vous devez remplacer votre demande synchrone avec une demande asynchrone et utiliser un rappel. Un exemple trop simplifié serait:

obj = do_async_ajax_call(function (data, success)
{
    if (success) 
    {  
        // continue...  
    } 
}); 

function do_async_ajax_call(callback)
{
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://mysite.com", true);
    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
            callback(xhr.responseXML, true);
        else if (xhr.readyState == 4)
            callback(null, false);
    }
    xhr.send();
}


3 commentaires

Cela serait normalement suffisant, mais je ne peux pas scinder le flux de fonctionnement (comme mis à jour dans la question). J'essaye une autre approche maintenant ...


C'est toujours possible de la diviser; Ceci est la transformation CPS (recherchez «Style de passage de continuation»; le paramètre de continuation est votre rappel). Vos variables d'état local sont simplement fermées dans la fonction de rappel. Les boucles deviennent des appels récursifs. Ce n'est pas si difficile ou obscur une fois que vous avez compris.


Je suis d'accord que c'est toujours possible, mais dans ce cas, ce n'était pas la meilleure solution (il y avait trop de variables d'état!) :) À la fin, j'ai utilisé le résultat des rappels précédents (ou un sondage régulier du serveur) pour mettre à jour le client- Côté avec une valeur mise en cache de l'appel synchrone si nécessaire, il n'a donc pas besoin d'appeler Ajax du tout.



0
votes

JavaScript est un seul thread. Donc, par définition, vous ne pouvez pas mettre à jour l'interface utilisateur pendant que vous êtes dans une boucle de marée. Cependant, à partir de Firefox 3.5, il a ajouté des javascripts multi-threads appelés webriers. Les travailleurs Web ne peuvent pas affecter l'interface utilisateur de la page, mais ils ne bloqueront pas non plus les mises à jour de l'interface utilisateur. Les travailleurs sont également soutenus par Chrome et Safari.
Problème est que même si vous déplacez votre appel AJAX en filetage d'arrière-plan et que vous attendez de l'exécution, les utilisateurs pourront appuyer sur les boutons et modifier des valeurs sur votre UI (et aussi loin que je comprenne, c'est ce que vous essayez de éviter). La seule chose que je peux suggérer d'empêcher que les utilisateurs puissent entraîner des modifications est une fileuse qui bloquera l'intégralité de l'interface utilisateur et ne permettra aucune interaction avec la page jusqu'à ce que l'appel Web renvoie.


1 commentaires

Je ne me dérange pas si les utilisateurs interagissent avec la page (et l'interaction est la file d'attente); Mais actuellement, lorsqu'un appel AJAX synchrone est exécuté dans Firefox, tout le navigateur gèle. C'est ce que je veux empêcher.