【问题标题】:Using JQuery, how to wait for both an AJAX call and its callback to finish before proceeding?使用 JQuery,如何在继续之前等待 AJAX 调用及其回调完成?
【发布时间】:2017-10-23 17:26:41
【问题描述】:

我的问题与this one 类似,但我无法用这些答案解决它。

简而言之,在页面加载时,ajax 调用会生成一个下拉选择元素,然后根据某些参数设置其默认值。
代码是这样的:

getList('country', null, q, 'category:customer', null);  
newReportSelection.apply($("#report"));  

function getList(field, val, q, fq, default_value) {
    $.get(... {  
      // call info
    },  function(result) {
      // appending the dropdown to DOM
    });
};

newReportSelection = function () {
    // determine and select default option
}  

getList 在不同的地方使用,所以我不能将这个(特定于页面加载)newReportSelection() 代码添加到 ajax 回调函数中。
在 getList() 调用周围放置一个承诺不会等待 Ajax 调用,因为它是异步的。
在 Ajax 调用周围放置一个等待它被发送,而不是等待回调函数被执行。
在回调函数周围放置一个也不起作用,因为 Ajax 部分等待它,但 getList() 由于异步性而继续运行。

即使在 Ajax 调用和回调函数上链接承诺有效,这看起来也是一个非常肮脏的解决方法并且不可取。
我有没有办法让 newReportSelection() 调用等到整个 getList() 完成,而无需手动将 Ajax 调用设置为async: false

提前致谢。

【问题讨论】:

  • 只需在附加到 DOM 的 ajax done 函数中调用 newReportSelection() 即可?
  • 正如我所提到的,我不能,因为 getList() 函数在多个地方被调用,而 newReportSelection() 部分仅适用于其中一种情况。
  • 如何在 getList 函数中提供一个新参数,该参数是您要触发的回调并在结果回调中调用该函数?如果在其他地方使用,只需检查您是否在结果函数中传递了回调,如果是,则执行回调,否则跳过回调
  • 这可能会起作用,但不会那么优雅(特别是对于其他调用,尽管您可以省略参数)。 freen-m 下面的答案解决了这个问题,而不影响其他呼叫,并且通过异步性更好地流动。感谢您的建议!

标签: javascript jquery ajax asynchronous promise


【解决方案1】:

从 $.get 返回延迟/承诺

function getList(field, val, q, fq, default_value) {
  return $.get(... {  
    // call info
  },  function(result) {
    // appending the dropdown to DOM
  });
};     

那么你可以在promise.done()方法中调用你的后续:

getList('country', null, q, 'category:customer', null).done(function() {
    newReportSelection.apply($("#report")); 
});

【讨论】:

  • 正要写这个:)
  • 成功了,非常感谢!我还不太习惯承诺,也没有意识到你可以通过这种方式传递它们来跟踪它们。
【解决方案2】:
var d1 = $.Deferred();
var d2 = $.Deferred();
var d3 = $.Deferred();

$.when( d1, d2, d3 ).done(function ( v1, v2, v3 ) {
  console.log( v1 ); // v1 is undefined
  console.log( v2 ); // v2 is "abc"
  console.log( v3 ); // v3 is an array [ 1, 2, 3, 4, 5 ]
});

d1.resolve();
d2.resolve( "abc" );
d3.resolve( 1, 2, 3, 4, 5 );

https://api.jquery.com/jquery.when/中提取

【讨论】:

  • 据我了解,这适用于您并排执行多个承诺并希望在继续之前解决所有承诺的情况。在我的情况下,它们是连续的(ajax 调用,完成回调时,完成其他功能时)所以这在这里不起作用,除非我弄错了?
  • 接受的答案看起来更好,但我的意思是这样的: $.when(getList(....)).done(function() { newReportSelection.apply($("#report ")); });
  • 我已经尝试过了(“在 getList() 调用周围放置一个承诺”),这样一旦函数退出就认为它已经完成,例如。只要它发送了ajax请求但没有等待它完成。这就是为什么返回请求的承诺(来自接受的答案)效果更好,尽管我仍然不确定为什么将承诺放在函数内部的 ajax 调用周围并没有等待回调结束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2011-02-07
  • 2011-02-15
  • 1970-01-01
  • 2015-12-22
相关资源
最近更新 更多