【发布时间】:2016-08-07 08:22:51
【问题描述】:
我有一个绑定到$someEl 的事件处理程序,它应该只在oRes 填充数据时执行,这些数据可以来自主要来源 (getData1()) 或备用来源 (getData2())。仅当主源超时时才从备份源请求数据。
如果主源没有超时,那么一切正常;然而,当备份getData2() 函数被调用时,dfd 永远不会被解析,所以当我点击$someEl 时没有任何记录。我怀疑它不起作用,因为 getData2() 中的 Deferred 对象正在覆盖 $someEl 点击处理程序所指的 dfd 变量。
我感觉我没有使用“最佳实践”模式来应用 Deferred/Promise。在这种情况下,如何让点击处理程序在超时后正确等待从主 AJAX 响应或辅助 AJAX 响应填充 oRes?
一些澄清说明:
-
getData1()必须在文档准备好后执行 -
$someEl.click()可能会在文档加载期间随时触发,因此需要在$(document).ready()之外定义事件处理程序 - 我坚持使用 jQuery 1.7.1
代码如下:
var oRes, dfd;
// Get data from primary source
function getData1() {
dfd = $.ajax({
...
success: function(data) {
oRes = data;
},
error: function(jqXHR, textStatus, errorThrown) {
if (textStatus==='timeout') getData2();
},
timeout: 10000 // 10-second timeout
});
}
// Get data from backup source
function getData2() {
dfd = $.ajax({...});
}
$someEl.click(function() {
dfd.done(function() {
console.log('This should only log when oRes is ready');
});
});
$(document).ready(function() {
getData1();
});
我已经用这支笔模拟了我的情况:http://codepen.io/thdoan/pen/pyVyKj
基本上,我无法让事件处理程序输出“数据准备就绪!”当 oRes 被填充时,无需在页面加载后手动单击该框。
【问题讨论】:
-
只是想指出,使用您当前的策略,每次单击 $someEl 都会将另一个回调绑定到延迟对象,因此当最终解决延迟时,它将运行您的回调 X 次,其中 X 是元素被点击的次数。这可能是您想要的行为,但只是想确保您意识到这一点。
-
@MattDiamond 感谢您指出这一点,非常好的一点:)。我已将代码更改为使用
.one('click', ...)。
标签: jquery promise jquery-deferred deferred