Javascript jquery$.when-是否有停止的方法。提前触发失败?

Javascript jquery$.when-是否有停止的方法。提前触发失败?,javascript,jquery,promise,Javascript,Jquery,Promise,根据$.when的jQuery文档,如果任何参数承诺失败,那么.when将不会等待,并将立即失败。它也不会取消其他承诺 有没有办法强迫$。什么时候才能真正等到它的所有承诺都完成?或者,我可以/应该使用其他方法吗? 可能是使用了错误的工具,但我试图在同时获取两个部分的数据时阻止UI(加载微调器)。我可以独立处理其中一个/两个部分的故障。当(且仅当)所有承诺都完成(成功或失败)时,我想取消页面阻塞 在下面的示例代码中,“callSvc”是一种测试方法,它使用字符串“服务”标识符、服务器睡眠(毫秒)以

根据$.when的jQuery文档,如果任何参数承诺失败,那么.when将不会等待,并将立即失败。它也不会取消其他承诺

有没有办法强迫$。什么时候才能真正等到它的所有承诺都完成?或者,我可以/应该使用其他方法吗?

可能是使用了错误的工具,但我试图在同时获取两个部分的数据时阻止UI(加载微调器)。我可以独立处理其中一个/两个部分的故障。当(且仅当)所有承诺都完成(成功或失败)时,我想取消页面阻塞

在下面的示例代码中,“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;
    });

对于multi arg
$.when()
Promise.all
,只要任何调用失败,规范就会失败。然而,使用小包装器方法,您可以将失败转化为(暂时的)成功。这相当于调用
catch
,但使用两个arg
然后调用:

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.
    });

好的,看来答案是否定的。相反,我必须手动管理自己的承诺/延期

以下是我最终使用的代码模式:

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为我指明了正确的方向

我们正在使用jquery 2.1.0,在节点承诺中也做了类似的事情。我们发现解决问题的方法是解决all调用中的所有承诺(即$.when)并添加成功标志。您可能会在承诺上链接一个
.catch()
。@FissureKing-我得到了。catch()不是一个函数,所以,可能我的jquery太旧了。@emery.noel,它是
Promise
上的一个方法,但是现在我看到,
callSvc
是另一个恰好有
then
方法的东西。很有趣!我要试试看!我尝试了几种不同的方法(包括复制/粘贴),但都不起作用。我碰到了epol的失败(正如预期的那样),然后是ebill的“然后”。。。但我永远不会进入“完成”阶段。如果我在“同步”上附加了一个“始终”,我会在第一次失败时立即进入它。@emery.noel它对我有效,并对手动按钮进行了一些调整:我在你的小提琴中看到你正在使用$。延迟对象,这与您发布的代码有点不同:)但是$.Deferred是我必须走的路。@emery.noel-Right,这是手动按钮调整之一;您的
callSvc
可能比按钮驱动的演示更加独立。没有你提供的一个完整的例子,这是我能给你的最好的例子。