多个AJAX请求乱序

时间:2013-11-22 23:35:12

标签: javascript jquery ajax html5 rest

我在这里有一个脚本,它执行多个AJAX请求以从REST服务获取多个股票报价。然而,我得到的结果是不正常的。

这是我的控制台日志序列TSLA - > TSLA - > AAPL - > TSLA - > AAPL - > ATT

我的代码中有什么不合适的地方吗?为什么我多次获得输出?

    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]);

        }

    });

3 个答案:

答案 0 :(得分:3)

问题出在handleSuccess - 它为每个结果增加jsonResultArray,并且每次调用回调:

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

我想你可以:

  1. 仅传递当前结果this.fCallback(jsonResult)(这会在每次结果到达时多次调用回调)。
  2. 或仅在所有结果都返回时运行回调。乍一看,似乎您可以简单地使用成员变量this.resultCount,在每个错误/成功处理程序上递增它,并将其与请求数进行比较。但如果你想同时运行多个QuoteService调用,这会变得有点复杂。

答案 1 :(得分:3)

由于您正在使用jQuery,因此只有在所有请求完成后才能调用回调。见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);
    });
});

答案 2 :(得分:1)

无法确定您的请求的响应顺序。请求可以遵循互联网上的不同路径,并且服务器可以以不同的顺序响应它们。您可以做的是等待所有请求都被响应,然后以正确的顺序使用它们。