拒绝Javascript承诺和错误处理

拒绝Javascript承诺和错误处理,javascript,ajax,error-handling,promise,es6-promise,Javascript,Ajax,Error Handling,Promise,Es6 Promise,我正试图用正确的方式来表示.then()中的故障 如果承诺没有失败(即,返回承诺的操作正确地完成了它的工作,例如返回状态200的AJAX请求),但我确定结果无效,通常我会弹出一个窗口,向用户解释问题,并执行“返回false;”以尽早退出该方法 然而,有了承诺,如果在.then()中,我想做一些类似的事情,我被引导相信我应该做的是抛出一个错误,并可能让这个错误被我所链接的.catch()捕获 我关心的是,我想区分承诺内的操作成功了,但我不喜欢其结果,以及承诺内的操作失败了 例如,如果我执行了一个A

我正试图用正确的方式来表示
.then()
中的故障

如果承诺没有失败(即,返回承诺的操作正确地完成了它的工作,例如返回状态200的AJAX请求),但我确定结果无效,通常我会弹出一个窗口,向用户解释问题,并执行“返回false;”以尽早退出该方法

然而,有了承诺,如果在.then()中,我想做一些类似的事情,我被引导相信我应该做的是抛出一个错误,并可能让这个错误被我所链接的.catch()捕获

我关心的是,我想区分承诺内的操作成功了,但我不喜欢其结果,以及承诺内的操作失败了

例如,如果我执行了一个AJAX调用,但404失败了,这实际上是不可恢复的,所以用一个弹出窗口来拒绝它似乎是合适的,比如说“出了什么问题”

但是,如果AJAX请求成功(返回状态200),但响应表明有问题(比如用户没有用正确的值填写字段),那么我希望以某种方式处理该问题,这可能不仅仅涉及带有消息的弹出窗口(例如,可能是DOM操作、红色文本等,如果是404,我可能不想做的事情)

下面是两个例子来更好地解释我的意思

第一个是带有回调的原始实现,第二个是带有承诺的实现(使用Q承诺库包装ajax调用,使其成为一个适当的承诺)

回调版本:

    $.ajax({
    url: "/cars/1",
    type: "GET",
    contentType: "application/json; charset=utf-8",
    dataType: "json"
})
.done(function (data) {
    if (!data.IsSuccessful) {
        //The request was successful (status 200), but the server is returning IsSuccessful=false
        alert(data.Message);//message says something like "we have that car in our catalogue but we don't have it in stock"
        return false;//early exit from .done()
    }

    //if it gets here, everything is good and I can do something with the result
})
.fail(function (data) {
    //The request actually failed due to a generic status 500 error which has something I don't necessarily want to expose in a popup to the user
    alert("Something went wrong");

});
承诺版本:

    var myPromise = Q(
    $.ajax({
        url: "/cars/1",
        type: "GET",
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    })
);

myPromise.then(function (data) {
    if (!data.IsSuccessful) {
        throw new Error(data.Message);
    }

    //all good, lets do something with the result
})
.catch(function (error) {

    //what is error?
    //How do I know if it's one that I want to show to the user or not?

}).done();
在promise版本中,如果请求返回404,它将立即在
.catch()
中结束,对吗

如果
data.issusccessful==false
,那么它也将在
中结束。catch()

如果我想以不同的方式对待这两次失败,我会怎么做

我没有打电话给任何地方的解决或拒绝,这有问题吗


我希望确保尽可能多地遵循最佳实践。

TL;DR:您可以使用,但一般来说,它们是用于


在promise版本中,如果请求返回404,它将立即在.catch()中结束,对吗

如果data.issusccessful==false,那么它也将在.catch()中结束

我没有打电话给任何地方的解决或拒绝,这有问题吗

一点也不。您没有使用
Promise
构造函数(您不需要它,因为您已经对ajax结果做出了承诺)

如果我想以不同的方式对待这两次失败,我会怎么做

抛出不同类型的错误,以便您能够区分它们。为它们命名、添加特殊属性、进行子类化(特别是在ES6中),或者只查看消息

有了承诺,如果在.then()中,我想做类似的事情,我已经被引导相信我应该做的是抛出一个错误

不一定。你可以像没有承诺时那样做——在回调中放入if-else(或者如果你愿意,可以提前返回if)

在控制流及其结果值方面

.then(function(res) {
    if (!res.isOK) {
        // do something
        return false;
    }
    // do something else
}).catch(function(err) {
    // handle something
})


它们几乎是等价的(除了
do something
中的异常,以及除了抛出
MyError
s之外的其他代码)。主要的区别是当您要链接其他
时。然后(…)
然后
捕获
之间调用。如果你不这样做,就选择你更喜欢的方法。

为什么不直接依靠状态码来完成他们的工作呢?为什么你会提供一个200响应,其中包含
isSuccessful:false
属性?2xx响应码都意味着请求成功。因为他可能希望显示一些只能由数据库检索的值,因此需要将该值返回给客户端。这将从AJAX中给出状态200。@Abayob可以返回非
200
@charlietfl How的标题中的数据。您能用JavaScript解释吗?您有示例吗?@Abayob您在服务器和检查响应状态,如果是自定义状态,请阅读作为$.ajax xhr object一部分的标题。谢谢你的回答。你能为我澄清一下你的最后一段吗?你是说如果我真的想将附加的.then()链接到.then()之外吗我要从中抛出一个异常,我需要注意它们不会被调用,因为它会直接跳转到.catch()?@Steviebob:是的,没错。这可能正是你想要的,也可能不是你想要的。如果你不想让它们被调用,并且仍然想使用
If
-
else
,你可以嵌套
然后
回调。
.then(function(res) {
     if (!res.isOK)
         throw new MyError(res);
     // do something else
}).catch(function(err) {
     if (err instanceof MyError) {
         // do something
         return false;
     }
     // handle something
})