根据jQuery文档$ .when,如果任何一个参数promise都失败了,那么.when将不再等待,并且将立即失败。它也不会取消其他承诺。
是否有一种方法可以强制$ .when实际等待其所有承诺都已完成?另外,我可以/应该使用其他方法吗?
也许是使用错误工具的情况,但是我试图阻止UI(加载微调器),同时获取2个部分的数据。我可以独立处理两个部分的失败。当(且仅当)所有承诺都完成(成功或失败)时,我才想取消阻止页面。
在下面的示例代码中,“ callSvc”是一种测试方法,该方法采用字符串“服务”标识符,以毫秒为单位的服务器睡眠状态以及指示Web调用是否失败的指示器。
callSvc("sync", 0, false)
.then(function (result) {
return $.when(
callSvc("ebill", 4000, false)
.then(function (a, b, c, d) {
debugger;
}),
callSvc("epol", 2000, true)
.done(function () {
// set up epol section with data
debugger;
})
.fail(function () {
// set up epol section for failure
debugger;
})
).done(function (ebill, epol) {
// just here to test ways to stop early-fail
debugger;
}).fail(function () {
// just here to test ways to stop early-fail
debugger;
})
}).fail(function (err) {
// show message
debugger;
}).always(function () {
// unblock the screen
debugger;
});
答案 0 :(得分:1)
对于多参数$.when()
或Promise.all
而言,只要任何调用失败,该规范就会失败。但是,使用小型包装方法,您可以将失败变成(临时)成功。这等效于调用catch
,但使用两个参数then
代替:
function wrapWithSuccessFlag(promise) {
return promise.then(
successfulValue => { return { success: true, value: successfulValue }; },
failureReason => { return { success: false, reason: failureReason }; });
}
callSvc("sync", 0, false).then(result => {
return $.when(
wrapWithSuccessFlag(callSvc("ebill", 4000, false)
.then(function (a, b, c, d) {
debugger;
})),
wrapWithSuccessFlag(callSvc("epol", 2000, true)
.done(function () {
// set up epol section with data
debugger;
})
.fail(function () {
// set up epol section for failure
debugger;
}))
).done(function (ebill, epol) {
// Determine whether ebill and epol succeeded or failed.
// You can also throw an error here using ebill or epol's reason,
// which gets you the error handling you're used to.
});
答案 1 :(得分:0)
好吧,答案似乎是否。相反,我不得不手动管理自己的承诺/延期。
这是我最终使用的代码模式:
var callSvc = function (svcName, sleep, shouldFail) {
return $.ajax{...};
}
callSvc("sync", 0, true)
.then(function (result) {
var ebillPromise = $.Deferred();
var epolPromise = $.Deferred();
callSvc("ebill", 4000, false)
.then(function (data) {
// ebill success
debugger;
ebillPromise.resolve();
}, function () {
// ebill fail
debugger;
ebillPromise.resolve();
});
callSvc("epol", 2000, true)
.then(function (data) {
// epol success
debugger;
epolPromise.resolve();
}, function () {
// epol fail
debugger;
epolPromise.resolve();
});
return $.when(
ebillPromise,
epolPromise
)
}).fail(function () {
debugger;
}).always(function () {
// unblock the screen
debugger;
});
之所以有效,是因为我的承诺从未被“拒绝”,所以我的$ .when()将等待。
但是,如果我们可以告诉JQuery等待,那肯定会很好。也许是“ $ .reallyWait()”函数...? :)
感谢@JeffBowman和@bhmahler让我指出正确的方向!