如何知道哪个$ .ajax承诺已经解决?

时间:2015-12-31 19:59:11

标签: javascript jquery promise

我正在使用jQuery ajax来请求数据,然后将数据制作成不同类型的图表或表格。

我已将想要运行的查询放入对象并发送请求。 runQuery()返回一个jQuery promise。承诺完成后返回的数据是正确的。 [编辑]由于ajax请求是异步运行的,因此它们可能无法按照发出的顺序[ / EDIT ]返回,我无法知道返回的数据是哪个查询是为了。

function refreshData(){
    for(var key in baseQueries){
        runQuery(baseQueries[key])
            .done(function(data){
                console.log("Query data for "+key);
                // want to call different charting functions
                // based upon which results are returned
            });
    }
};

runQuery(obj) { // "public" function
    var params = $.extend({},defaults,obj);
    return sendRequest(queryUrl,params)
}

sendRequest(url,data,method){ // "private" function
    method = method || "GET";

    return $.ajax({
            type:method,
            url:url,
            dataType:"json",
            data:data
        })
        .fail(function(error){
            console.log(error);
        });
}

在这种情况下,控制台在baseQueries对象的最后一次迭代中记录key的值。例如,如果我的baseQueries对象中有三个项目,而我的baseQueries对象中的最后一个项目是

"This-is-the-last-query":"queryparam1,queryparam2,etc"

然后,当所有三个ajax调用解析时,我得到三个“This-is-the-last-query”日志。这没有用,因为它没有告诉我数据属于哪个查询。

这类似于the infamous javascript loop issue的想法,但我真的不知道如何在这里使用将值附加到DOM元素的答案。

如何匹配哪个查询调用与哪个承诺?如何通过ajax调用传递密钥并使用promise数据返回它。

修改 不要认为这是指示线程的副本。我看到它们是如何相关的,但不是如何使用它来解决这个问题。建议的重复没有提到jquery,ajax,promises或异步问题。它也被标记为另一个没有提及任何这些东西的线程的副本。

显示的解决方案要么使用dom元素来保存onclick所需的信息(这里不适用),要么添加一个闭包,但是当已经存在数据时我不知道怎么做返回。

2 个答案:

答案 0 :(得分:1)

如果你传递jQuery ajax一个它一无所知的参数,它会忽略它,你可以在以后访问它。

在这里,我们为您的额外值(mykey)设置一个参数,然后我们可以在以后为我们正在使用的实例访问它:

function refreshData() {
  for (var key in baseQueries) {
    runQuery(baseQueries[key], key)
      .done(function(data) {
        console.log("Query data for " + this.myKey);
       // "this" here is the ajax for which the promise (ajax) gets resolved,
       // and we return that promise so it works here.
        // want to call different charting functions
        // based upon which results are returned
      });
  }
};

runQuery(obj,key) { // "public" function
  var params = $.extend({}, defaults, obj);
  return sendRequest(queryUrl, params,,key)
}

sendRequest(url, data, method, key) { // "private" function
  method = method || "GET";

  return $.ajax({
      type: method,
      url: url,
      dataType: "json",
      data: data,
      myKey:key
    })
    .fail(function(error) {
      console.log(error);
    });
}

答案 1 :(得分:0)

如果你想检查jquery承诺是否已经解决,你可以查看jqueryPromise.state(),它会返回pendingresolvedrejected,具体取决于州。
如果您要发送多个ajax requests并且想知道它们何时完成,您可以将它们放入数组([$.ajax(...),$.ajax(...)])并将其传递给 $.when喜欢

var requests = [$.ajax(...),$.ajax(...)];
$.when.apply($, requests).done(function() {
  console.log('all requests completed');
});

如果你想用承诺建立一些复杂的东西我会建议使用bluebird或更简单的rsvp