【问题标题】:Is it possible to create and use a Deferred object directly with AJAX?是否可以直接使用 AJAX 创建和使用 Deferred 对象?
【发布时间】:2014-04-11 14:41:49
【问题描述】:

我有一个应用程序,当用户单击特定按钮时会发送一些 AJAX 请求。

但是,我也有类似于“取消”按钮的东西,它应该中止所有请求。

我目前使用$.when 来处理所有发送的请求,并在它返回的Promise 对象上添加了适当的回调。

然而,$.when 返回一个Promise 对象的事实令人沮丧,因为它没有(故意)包含Deferred 必须控制请求的方法,如下代码所示:

使用 $.when

var x = $.when($.get('/'), $.get('/')); // .then(function() {console.log('done');});

Object.keys(x); 
// ["state", "always", "then", "promise", "pipe", "done", "fail", "progress"]

使用一个 AJAX 请求(jqXHR 实现了 Deferred 接口)

var x = $.get('/');

Object.keys(x); 
// ["readyState", "getResponseHeader", "getAllResponseHeaders", "setRequestHeader", "overrideMimeType", "statusCode", "abort", "state", "always", "then", "promise", "pipe", "done", "fail", "progress", "complete", "success", "error"]

我正在寻找一种方法来检索Deferred 对象,或者将$.when 替换为执行相同但返回Deferred 对象的方法。从那里,我将能够调用合适的拒绝/中止方法。

这可能吗?

【问题讨论】:

  • 取消不在 Promise/Deferred 接口上,这是一个 ajax-only 方法,需要手动处理。另请注意,jqXHR 没有实现 Deferred 接口(它没有reject/resolve 方法),而是实现了 Promise 接口。
  • 您可以将您的请求推送到一个数组中,如下所示:jsfiddle.net/Q3BV9 Aborting request 将拒绝延迟对象
  • @Bergi 我明白了,感谢您指出这一点! @A.Wolff 这是我考虑过的一种可能性。它与其他请求一起工作的方式是,它存储当前活动的(单个)请求,并在请求解决之前调用.abort。我想我需要好好考虑一下如何构建它,无论如何谢谢!

标签: javascript jquery ajax promise jquery-deferred


【解决方案1】:

您可以将请求放入一个数组中,并在需要时单独中止它们。

为此,您可以在$.when 上使用.apply。例如:

var requests = [$.get('/'), $.get('/')];
$.when.apply($,requests).then(function(res1,res2){
      //access results here
});

// aborting:
requests.forEach(function(x){ return x.abort();});

延迟对象仅用于从回调 API 创建承诺。您不能“检索”已经存在的承诺的延迟对象。仅使用它创建新的。

您可能还想查看 Domenic 的 last()

【讨论】:

  • 哦,我没看到 A. Wolff 已经提出了类似的解决方案。先给他建议的道具,这是他的一个例子jsfiddle.net/Q3BV9
  • 为了清楚起见,我实现了一个类似的解决方案。以后阅读本文的任何人都应该知道,在 Promise 对象中中止一个请求将触发顶部 Promise 对象中的拒绝触发器。这是因为延迟对象必须成功解决所有条件才能被视为成功。如果任何 1 个条件失败,将立即被视为拒绝。 (但是,这不会中止其他条件的运行)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-26
  • 2016-04-10
  • 1970-01-01
相关资源
最近更新 更多