Ich habe hier ein Skript, das mehrere AJAX-Anforderungen ausführt, um mehrere Börsenkurse von einem REST-Service zu erhalten. Die Ergebnisse, die ich erhalte, sind jedoch nicht in Ordnung.

Hier ist meine Konsolenprotokollsequenz TSLA -> TSLA -> AAPL -> TSLA -> AAPL -> ATT

Ist in meinem Code etwas nicht in Ordnung? Warum bekomme ich die Ausgabe mehrmals?

    var jsonResultArray = new Array();
    var StockQuotes = {};
    /**
    * Define the QuoteService.
    * First argument is symbol (string) for the quote. Examples: AAPL, MSFT, JNJ, GOOG.
    * Second argument is fCallback, a callback function executed onSuccess of API.
    */
    StockQuotes.QuoteService = function(sSymbol, fCallback) {
        console.log("Entering quote serivce");
        this.symbol = sSymbol;
        this.fCallback = fCallback;
        this.DATA_SRC = "http://dev.markitondemand.com/Api/v2/Quote/jsonp";
        for(index in sSymbol){
            this.makeRequest(sSymbol[index]);
            console.log(sSymbol[index])
        }
    };
    /**
    * Ajax success callback. fCallback is the 2nd argument in the QuoteService constructor.
    */
    StockQuotes.QuoteService.prototype.handleSuccess = function successHandler(jsonResult) {
        console.log("Entering handle success");
        jsonResultArray.push(jsonResult)
        this.fCallback(jsonResultArray);
        if(this.xhr) {this.xhr.abort();}
    };
    /**
    * Ajax error callback
    */
    StockQuotes.QuoteService.prototype.handleError = function errorHandler(jsonResult) {
        console.log("Entering handle error");
        console.error(jsonResult.Message);
    };
    /**
    * Starts a new ajax request to the Quote API
    */
    StockQuotes.QuoteService.prototype.makeRequest = function requestHandler(currentSymbol) {
        console.log("Entering make request");
        //Abort any open requests
    //    while (this.xhr) {  }
        //Start a new request
        this.xhr = $.ajax({
            data: { symbol: currentSymbol},
            url: this.DATA_SRC,
            dataType: "jsonp",
            async: "false",
            success: this.handleSuccess,
            error: this.handleError,
            context: this
        });
    };

    new StockQuotes.QuoteService(["T","AAPL","TSLA"], function finalOutput(jsonResultArray) {
        console.log("Entering final output");
        for(i in jsonResultArray){
            console.log(i);

            //If all goes well, your quote will be here.
            console.log(jsonResultArray[i]);

        }

    });
1
Vinit Asher 23 Nov. 2013 im 03:35

3 Antworten

Beste Antwort

Das Problem liegt in handleSuccess - es erweitert jsonResultArray für jedes Ergebnis und ruft jedes Mal den Rückruf auf:

jsonResultArray.push(jsonResult)
this.fCallback(jsonResultArray);

Ich nehme an, Sie könnten entweder:

  1. Übergeben Sie stattdessen nur das aktuelle Ergebnis this.fCallback(jsonResult) (dies würde den Rückruf mehrmals aufrufen, wenn jedes Ergebnis eintrifft).
  2. ODER führen Sie den Rückruf nur aus, wenn alle Ergebnisse zurückgegeben wurden. Auf den ersten Blick scheint es so, als könnten Sie einfach eine Mitgliedsvariable this.resultCount verwenden, sie bei jedem Fehler- / Erfolgs-Handler erhöhen und mit der Anzahl der Anforderungen vergleichen. Dies wird jedoch etwas komplexer, wenn Sie jemals mehrere QuoteService Aufrufe gleichzeitig ausführen möchten.
3
McGarnagle 22 Nov. 2013 im 23:46

Da Sie jQuery verwenden, können Sie Ihren Rückruf auf einfache Weise nur dann aufrufen, wenn alle Anforderungen abgeschlossen sind. Siehe http://api.jquery.com/jQuery.when/

// I removed error handling, you'll have to do that
StockQuotes.QuoteService = function(sSymbol, fCallback) {
    var reqs = [];
    for (var i=0; i < sSymbol.length; i++) {
        reqs.push($.ajax({
            data: { symbol: sSymbol[i]},
            url: "http://dev.markitondemand.com/Api/v2/Quote/jsonp",
            dataType: "jsonp",
            async: "false"
       }));
    }

    $.when.apply($, reqs).done(function(){
        fCallback.apply(arguments);
    });
});
3
Juan Mendes 22 Nov. 2013 im 23:59

Es gibt keine Möglichkeit zu bestimmen, auf welche Reihenfolge Ihre Anfragen beantwortet werden. Die Anforderungen können im Internet unterschiedlichen Pfaden folgen, und der Server kann in einer anderen Reihenfolge darauf antworten. Sie können warten, bis alle Anfragen beantwortet wurden, und dann in der richtigen Reihenfolge mit ihnen arbeiten.

1
sbking 22 Nov. 2013 im 23:40