我何时应该拒绝承诺?

时间:2021-12-03 19:43:40

I'm writing some JS code that uses promises. For example, I open a form pop-up and I return a jQuery Deferred object. It works like this:

我正在写一些使用promises的JS代码。例如,我打开一个表单弹出窗口,然后返回一个jQuery Deferred对象。它的工作原理如下:

  • If the user clicks OK on the form, and it validates, the Deferred resolves to an object representing the form data.

    如果用户在表单上单击“确定”并进行验证,则“延迟”将解析为表示表单数据的对象。

  • If the user clicks Cancel, then the Deferred resolves to a null.

    如果用户单击“取消”,则“延迟”将解析为空。

What I'm trying to decide is should the Deferred instead reject, instead of resolve? More generally, I'm wondering when should I resolve to something like a null object, and when should I reject?

我想要决定的是Deferred应该拒绝而不是解决?更一般地说,我想知道什么时候应该解决类似空对象的问题,什么时候应该拒绝?

Here's some code demonstrating the two positions:

这里有一些代码展示了两个位置:

// Resolve with null.
var promise = form.open()
    .done(function (result) {
        if (result) {
            // Do something with result.
        } else {
            // Log lack of result.
        }
    });

// Reject.
var promise = form.open()
    .done(function (result) {            
        // Do something with result.            
    })
    .fail(function () {
        // Log lack of result.
    });

3 个解决方案

#1


4  

The semantics of your two strategies are not really the same. Explicitly rejecting a deferred is meaningful.

你的两种策略的语义并不完全相同。明确拒绝延期是有意义的。

For instance, $.when() will keep accumulating results as long as the deferred objects it is passed succeed, but will bail out at the first one which fails.

例如,只要传递的延迟对象成功,$ .when()将继续累积结果,但会在第一个失败的对象中挽救。

It means that, if we rename your two promises promise1 and promise2 respectively:

这意味着,如果我们分别重命名你的两个promises promise1和promise2:

$.when(promise1, promise2).then(function() {
    // Success...
}, function() {
    // Failure...
});

The code above will wait until the second form is closed, even if the first form is canceled, before invoking one of the callbacks passed to then(). The invoked callback (success or failure) will only depend on the result of the second form.

上面的代码将等到第二个表单关闭,即使第一个表单被取消,在调用传递给then()的其中一个回调之前。调用的回调(成功或失败)仅取决于第二种形式的结果。

However, that code will not wait for the first form to be closed before invoking the failure callback if the second form is canceled.

但是,如果第二个表单被取消,那么在调用失败回调之前,该代码不会等待第一个表单被关闭。

#2


2  

Since it's user-controlled, I wouldn't treat it as a "failure". The first option seems cleaner.

由于它是用户控制的,我不会将其视为“失败”。第一种选择似乎更清洁。

#3


0  

Well, in both cases you would do something different, so i would say always either resolve it, or reject it. Do your form post on resolve, and on reject do nothing. Then, on always, close the form.

好吧,在这两种情况下你会做一些不同的事情,所以我会说要么总是解决它,要么拒绝它。你的表格发布决定,拒绝什么都不做。然后,始终关闭表单。

var promise = form.open()
.done(function (result) {            
    // Do something with result.            
})
.fail(function () {
    // Log lack of result.
})
.always(function() {
    // close the form.
})

If you aren't rejecting on cancel, when are you ever rejecting at all? at that point, why use a deferred object? You could reject on input error, but then you would have to generate a whole new promise if you wanted to allow them to fix it.

如果你没有拒绝取消,你什么时候拒绝?那时,为什么要使用延迟对象?您可以拒绝输入错误,但如果您想让它们修复它,您将不得不生成一个全新的承诺。


Deferreds don't really seem like the right thing to use here. I'd just use events.

延迟在这里看起来并不合适。我只是使用事件。

#1


4  

The semantics of your two strategies are not really the same. Explicitly rejecting a deferred is meaningful.

你的两种策略的语义并不完全相同。明确拒绝延期是有意义的。

For instance, $.when() will keep accumulating results as long as the deferred objects it is passed succeed, but will bail out at the first one which fails.

例如,只要传递的延迟对象成功,$ .when()将继续累积结果,但会在第一个失败的对象中挽救。

It means that, if we rename your two promises promise1 and promise2 respectively:

这意味着,如果我们分别重命名你的两个promises promise1和promise2:

$.when(promise1, promise2).then(function() {
    // Success...
}, function() {
    // Failure...
});

The code above will wait until the second form is closed, even if the first form is canceled, before invoking one of the callbacks passed to then(). The invoked callback (success or failure) will only depend on the result of the second form.

上面的代码将等到第二个表单关闭,即使第一个表单被取消,在调用传递给then()的其中一个回调之前。调用的回调(成功或失败)仅取决于第二种形式的结果。

However, that code will not wait for the first form to be closed before invoking the failure callback if the second form is canceled.

但是,如果第二个表单被取消,那么在调用失败回调之前,该代码不会等待第一个表单被关闭。

#2


2  

Since it's user-controlled, I wouldn't treat it as a "failure". The first option seems cleaner.

由于它是用户控制的,我不会将其视为“失败”。第一种选择似乎更清洁。

#3


0  

Well, in both cases you would do something different, so i would say always either resolve it, or reject it. Do your form post on resolve, and on reject do nothing. Then, on always, close the form.

好吧,在这两种情况下你会做一些不同的事情,所以我会说要么总是解决它,要么拒绝它。你的表格发布决定,拒绝什么都不做。然后,始终关闭表单。

var promise = form.open()
.done(function (result) {            
    // Do something with result.            
})
.fail(function () {
    // Log lack of result.
})
.always(function() {
    // close the form.
})

If you aren't rejecting on cancel, when are you ever rejecting at all? at that point, why use a deferred object? You could reject on input error, but then you would have to generate a whole new promise if you wanted to allow them to fix it.

如果你没有拒绝取消,你什么时候拒绝?那时,为什么要使用延迟对象?您可以拒绝输入错误,但如果您想让它们修复它,您将不得不生成一个全新的承诺。


Deferreds don't really seem like the right thing to use here. I'd just use events.

延迟在这里看起来并不合适。我只是使用事件。