Jquery 延迟 - 第二次失败被意外调用

Jquery Deferreds - second fail being called unexpectedly

我有一个排序功能,基本上有两个 REST 步骤 - 步骤 1 和步骤 2。 我正在按以下方式处理它 - 调用 step1 并有一个 fail 和一个 then 处理程序,然后是第二个调用 - step2 有它自己的 fail 然后处理程序。

self.step1()
    .fail(self.onStep1Fail.bind(self))
    .then(self.onStep1Done.bind(self))
    .then(self.step2.bind(self))
    .fail(self.onStep2Fail.bind(self))
    .then(self.onStepDone.bind(self));

这个序列我的解读是调用了step1,如果失败,就会调用step1的fail方法。如果step1成功,则依次调用step1Done和step2,然后step2判断是调用step2Fail还是Step2Done。

但由于某种原因,当 step1 失败时,同时调用 Step1Fail 和 Step2Fail - 这是意外的。有谁知道为什么?另外,我怎样才能改变它来实现我正在尝试的 - 仅在实际执行 step2 之后才调用 step2Fail。

我是通过以下方法实现的:

    var handled = false;

    function onCatch(handler) {
        if (!handled) {
            handled = true;
            handler.call(self, Array.prototype.slice.call(window.Array.apply(null, arguments), 1));
        }
        return $.Deferred().reject().promise();
    }

    self.step1()
        .catch(onCatch.bind(self, self.step1Fail))
        .then(self.step1Done.bind(self))
        .then(self.step2.bind(self))
        .catch(onCatch.bind(self, self.step2Fail))
        .then(self.step2Done.bind(self));

但我正在寻找是否有更简单的方法。

fail 只是附加一个失败处理程序,没有任何回调链,它 returns 输入延迟。

step1() 失败时,整个链都会这样做,即链中的每个承诺都会被拒绝。并且每个承诺的失败处理程序都将被触发,在您的情况下 onStep1FailonStep2Fail.

如果您希望 onStep2… 处理程序仅在执行 step2 时被调用,请不要将它们放在整个链上:

self.step1()
.fail(self.onStep1Fail.bind(self))
.then(self.onStep1Done.bind(self))
.then(function(step1doneResult) {
    return self.step2(step1doneResult)
    .fail(self.onStep2Fail.bind(self))
    .then(self.onStepDone.bind(self));
});

而且我建议完全不要使用 fail 方法,因为它缺少链接。相反,使用 then:

的第二个参数
self.step1()
.then(self.onStep1Done.bind(self), self.onStep1Fail.bind(self))
.then(function(step1handlerResult) {
    return self.step2(step1handlerResult)
    .then(self.onStepDone.bind(self), self.onStep2Fail.bind(self));
});