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

时间:2017-03-21 12:02:15

标签: javascript jquery promise jquery-deferred deferred

我有一个基本上有两个REST步骤的排序功能 - 第1步和第2步。 我按照以下方式处理它 - 调用step1并为其执行失败和处理程序,然后执行第二次调用 - step2使用自己的失败然后处理程序。

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 - 这是意料之外的。有谁知道为什么?另外,我怎样才能改变这个以实现我的目的 - 只有在第二步实际执行后才调用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));

但我希望看看是否有更简单的方法。

1 个答案:

答案 0 :(得分:0)

fail只需附加一个失败处理程序,没有任何回调链接,它会返回延迟的输入。

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));
});
相关问题