【问题标题】:How to know which $.ajax promise has resolved?如何知道哪个 $.ajax 承诺已解决?
【发布时间】:2016-01-01 23:41:43
【问题描述】:

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

我已将要运行的查询放入对象并发送请求。 runQuery() 返回一个 jQuery 承诺。承诺完成时返回的数据是正确的。 [Edit]由于 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 调用传递密钥并将其与承诺数据一起返回。

编辑 不要认为这是指定线程的副本。我看到它们是如何相关的,但不知道如何使用它来解决这个问题。建议的副本未提及 jquery、ajax、promise 或异步问题。它也被标记为另一个没有提及任何这些事情的线程的重复。

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

【问题讨论】:

  • 回调中的key 值需要来自data 响应,例如data.key.
  • @Jasen 我该怎么做?数据是从 $.ajax 调用返回的,我不知道如何更改从服务器返回的内容。
  • 或许在这里显示 runQuery 代码?
  • 将您的问题改写为:“如何检索为每个 ajax 调用更改的值” - 因为您真正想要的是每个 ajax 调用的“键”值,我认为这会做: jsfiddle.net/ecpprfpv
  • 谢谢,确实有效!这对我来说似乎有点神奇,就像突然之间这有一个 myKey 属性,如果我正在查看代码,我是否能够弄清楚“this”是 $.ajax() 调用。但是,它有效,对吧?

标签: javascript jquery promise


【解决方案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);
    });
}

【讨论】:

    【解决方案2】:

    如果您想检查 jquery 承诺是否已解决,您可以使用 jqueryPromise.state() 进行检查,根据状态返回 pendingresolvedrejected
    如果您要发送多个 ajax requests 并且您想知道它们何时完成,您可以将它们放入数组 ([$.ajax(...),$.ajax(...)]) 并将其传递给 $.when点赞

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

    如果你想用 Promise 构建复杂的东西,我建议使用 bluebird 或不太复杂的 rsvp

    【讨论】:

      猜你喜欢
      • 2018-04-02
      • 2018-10-02
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多