34 votes

Quelle est la meilleure façon de montrer la progression d'un appel Ajax?

J'ai un appel Ajax qui met à jour 5 000 enregistrements dans une base de données, cela prend donc beaucoup de temps. J'ai un Ajax "Loading image" montrant que quelque chose se passe, mais je cherche une meilleure façon de montrer "Updating 50 of 5000 ...", "Updating 200 of 5000", ou quelque chose comme ça.

Quelle est la meilleure façon de faire quelque chose comme ça dans Ajax / jQuery sans faire 5000 publications différentes?

23voto

Zain Shaikh Points 3324

Le mieux je pense est à l'aide de la Comète.

Dans la Comète de style applications, le serveur peut essentiellement à envoyer des données au client (au lieu de la demande du client, des données à partir du serveur, encore et encore.). Le client doit uniquement se connecter à un serveur une fois. et puis serveur va continuer à pousser données vers le client.

De Wikipedia:

La comète est une technique de programmation qui permet aux serveurs web pour envoyer des données au client sans avoir besoin pour le client d'en faire la demande. Il permet de créer des event-driven web applications qui sont hébergées dans le navigateur.

Et maintenant, nous allons voir comment la Comète œuvres. Voir la suite le code côté serveur. ici, un while boucle est utilisée, vous pouvez définir votre propre condition. Dans la boucle while, la page écrit un datetime et les bouffées de chaleur et puis dort pendant 1/2 secondes.

ASP.NET la page code-behind: le Service.aspx.cs

public static string Delimiter = "|";

protected void Page_Load(object sender, EventArgs e)
{
    Response.Buffer = false;

    while (true)
    {
        Response.Write(Delimiter
            + DateTime.Now.ToString("HH:mm:ss.FFF"));
        Response.Flush();

        // Suspend the thread for 1/2 a second
        System.Threading.Thread.Sleep(500);
    }

    // Yes I know we'll never get here,
    // it's just hard not to include it!
    Response.End();
}

Côté Client code JavaScript

Seulement en faire la demande une fois, et puis garder le contrôle des données dans l' readyState === 3 de XMLHttpRequest.

function getData()
{
    loadXMLDoc("Service.aspx");
}

var req = false;
function createRequest() {
    req = new XMLHttpRequest(); // http://msdn.microsoft.com/en-us/library/ms535874%28v=vs.85%29.aspx
}

function loadXMLDoc(url) {
    try {
        if (req) { req.abort(); req = false; }

        createRequest();

        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send("");
        }
        else { alert('unable to create request'); }
    }
    catch (e) { alert(e.message); }
}

function processReqChange() {
    if (req.readyState == 3) {
        try {
            ProcessInput(req.responseText);

            // At some (artibrary) length   recycle the connection
            if (req.responseText.length > 3000) { lastDelimiterPosition = -1; getData(); }
        }
        catch (e) { alert(e.message); }
    }
}

var lastDelimiterPosition = -1;
function ProcessInput(input) {
    // Make a copy of the input
    var text = input;

    // Search for the last instance of the delimiter
    var nextDelimiter = text.indexOf('|', lastDelimiterPosition + 1);
    if (nextDelimiter != -1) {

        // Pull out the latest message
        var timeStamp = text.substring(nextDelimiter + 1);
        if (timeStamp.length > 0) {
            lastDelimiterPosition = nextDelimiter;
            document.getElementById('outputZone').innerHTML = timeStamp;
        }
    }
}

window.onload = function () { getData(); };

Référence

4voto

mrjames Points 204

Je laisserais la fonction qui effectue le gros enregistrement de mise à jour dans une variable SESSION sa progression actuelle après chaque mise à jour (ou autant), et utiliser un script AJAX distinct pour récupérer cette valeur de progression de la SESSION et laisser JavaScript l'utiliser pour mettre à jour votre barre de progression / texte.

2voto

Spain Train Points 442

Je suppose que vous utilisez actuellement un POST pour tous les enregistrements de la mise à jour par lots et placez l'image de chargement entre l'appel et le retour.

Plutôt que de faire attendre le serveur pour revenir jusqu'à la fin de la mise à jour, faites-le revenir immédiatement avec un ID spécial pour cette mise à jour par lots. Ensuite, implémentez un appel serveur qui renvoie l'état de la mise à jour par lots, que votre boîte de dialogue de progression peut appeler pour signaler la progression.

 var progressCallback = function(data){
  //update progress dialog with data
  //if data does not indicate completion
    //ajax call status function with "progressCallback" as callback
});
//ajax call status function with "progressCallback" as callback
 

2voto

Noufal Ibrahim Points 32200

Je déclencherais un rappel Ajax une fois toutes les n millisecondes qui peut demander combien de temps est fait (par exemple, le nombre d'enregistrements mis à jour) et l'utiliser pour afficher une barre de progression. Quelque chose comme la façon dont cela fonctionne.

2voto

user406905 Points 1004

Vous pourriez mettre à jour le tampon de réponse avec un progrès, les bouffées de chaleur de votre tampon de réponse périodiquement à partir du serveur.

Mais vous pouvez avoir de la difficulté à lire une requête avant de terminer par xhttpr. Vous pourriez être en mesure de faire votre demande via une iframe, et pour que la charge en cours via le streaming http'.

Mais même cela peut être louche. HTTP n'est pas destiné à transférer des choses fragmentaire/fragmenté. Comme d'autres, il serait préférable de séparer les appels suivants pour obtenir le statut de l'opération.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X