javascript - 拒绝 Javascript Promise 和错误处理

标签 javascript ajax error-handling promise es6-promise

我正在尝试用正确的方法来指示 .then() 中的失败。

如果 promise 没有失败,(即返回 promise 的操作正确地完成了它的工作,例如返回状态 200 的 AJAX 请求),但我认为结果无效,通常我会做一个弹出窗口,向用户解释问题,然后做一个“return false”;提前退出方法。

然而,有了 promise ,如果在 .then() 中,我想做类似的事情,我被引导相信我应该做的是抛出一个错误,并且大概让这个被捕获.catch() 我已经链接上了。

我担心的是,我想区分成功但我不喜欢其结果的 promise 操作和失败的 promise 操作。

例如,如果我执行一个 AJAX 调用并且它失败并显示 404,这实际上是不可恢复的,因此用一个弹出窗口说“出了点问题”来拒绝似乎是合适的。

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

下面是 2 个示例,可以更好地解释我的意思。

第一个是带有回调的原始实现,第二个是带有 promises 的实现(使用 Q promise 库包装 ajax 调用以使其成为正确的 promise)。

回调版本:

    $.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");

});

promise 版本:

    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.IsSuccessful==false,那么它也会在 .catch() 中结束吗?

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

我没有在任何地方调用 resolve 或 reject,这有问题吗?

我想确保我尽可能地遵循最佳实践。

最佳答案

TL;DR:可以使用rejections for control flow , 但一般来说它们是 exceptional cases only


In the promise version, if the request returns a 404 it will end up in the .catch() immediately right?

是的。

If data.IsSuccessful==false, then it will also end up in the .catch()?

是的。

I'm not calling resolve or reject anywhere, is that problematic?

完全没有。您没有使用 Promise 构造函数(您不需要它,因为您已经对 ajax 结果做出了 promise )。

What if I want to treat both failures differently, how would I go about that?

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

with promises, if from within the .then(), I want to do something similar, I've been lead to believe that what I should do is throw an error instead

不一定。您可以像不使用 promises 那样做 - 在回调中放置一个 if-else(或者如果您愿意,可以提前返回一个 if)。

在控制流及其结果值方面,

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

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

几乎是等价的(除了 do something 中的异常和抛出 MyError 之外的代码)。主要区别在于当您想要在 thencatch 之间链接额外的 .then(...) 调用时。如果您不这样做,请选择您更喜欢的任何内容。

关于javascript - 拒绝 Javascript Promise 和错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37364958/

相关文章:

javascript - Angular Js $httpParamSerializer 和 jQuery $.ajax

javascript - jQuery nextUntil id < number 或替代方案

javascript - 如何使用 ASP.Net 中的 PageMethods 将多维数组从 Javascript 传递到服务器

javascript - 使用 dojo 在表单上显示成功/失败消息

eclipse - 为FB Eclipse 4.5安装BIRT时出错

node.js - 如何按照存储库模式从 nodeJS 应用程序中的服务和存储库中抛出错误

asp.net-mvc-3 - .NET MVC Server_GetLastError 总是返回缺少 View 错误

javascript - 如何将 CSS 参数链接到 javascript img?

javascript - 在 cluetip 中使用 google charts api 并通过 ajax 显示内容

c# - asp mvc Controller 从 ajax 接收空值