拒绝Javascript承诺和错误处理 [英] Rejecting Javascript Promises And Error Handling

查看:208
本文介绍了拒绝Javascript承诺和错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



如果承诺没有失败,()即,返回承诺的操作可以正常工作,例如返回状态200的AJAX请求),但是我决定结果无效,通常我会做一个弹出窗口,向用户解释问题并做一个返回假;要尽早退出这个方法。



然而,有了promise,如果从.then()里面,我想做类似的事情,我一直在相信我应该做的是抛出一个错误,可能让我被链接的.catch()捕获。



我担心的是我想要区分承诺中的成功,但我不喜欢的结果的操作,以及承诺中的失败操作。



例如,如果我执行一个AJAX调用,它失败了一个404,这不是真的可以恢复,所以似乎适当的拒绝一个弹出窗口说出了问题。
但是,如果AJAX请求成功(返回状态200),但响应表示某事不正确(就像用户没有填写一个具有正确值的字段),那么我会喜欢以某种方式来处理,这可能不仅仅是一个弹出窗口的消息(例如,可能是DOM操作,红色文本等,如果它是404,我可能不想做的事情)。



下面是两个例子来更好的说明我的意思。
第一个是具有回调的原始实现,第二个是具有承诺(第二个是承诺)(用Q promise库包装ajax调用以使其成为一个适当的承诺)。



回拨版本:

  $ .ajax({
url:/ cars / 1,
类型:GET,
contentType:application / json; charset = utf-8,
dataType:json
})
.done(function(data) {
if(!data.IsSuccessful){
//请求成功(状态200),但服务器正在返回IsSuccessful = false
alert(data.Message); // message说我们有这辆车在我们的目录,但我们没有它有库存
返回false; //提前退出.done()
}

//如果它在这里,一切都很好,我可以做一些结果
})
.fail(function(data){
//该请求实际上由于一般的状态500错误有一些我不一定w蚂蚁在弹出窗口中暴露给用户
alert(Something wrong 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);
}

//所有好的,让我们做一些结果
})
.catch(function(error){

//什么是错误?
//如何知道是否要向用户显示?

})。done();

在承诺版本中,如果请求返回404,最终将在.catch()马上对吧?


如果data.IsSuccessful == false,那么它也将最终在.catch()中?



如果我想同时对待这两种失败,我该怎么办?



我不是在任何地方打电话或拒绝这个问题吗?



我想确保我尽可能遵循最佳做法。

解决方案

p> TL; DR:您可以使用拒绝控制流程,但一般来说,它们仅适用于特殊情况







在承诺版本中,如果请求返回404,它将立即在.catch()中最终出现。



如果data.IsSuccessful == false,那么它将还有最后一个.catch()?


是的。


我不是在任何地方打电话解决或拒​​绝,是否有问题?


根本没有。您没有使用 Promise 构造函数(您不需要,因为您已经有ajax结果的承诺)。


如果我想同时对待这两种失败,我该怎么办?


抛出不同种类的错误,以便您可以区分它们。给他们的名字,添加特殊属性,做子类化(特别是在ES6中),或者只是看看消息。


在.then()中,我想做类似的事情,我一直在相信我应该做的是抛出一个错误


不一定。你可以做的完全一样,没有你的承诺 - 把一个if-else放在回调中(或者如果你喜欢早点回报)。



的控制流及其结果值,

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

  .then(function(res){
if(!res.isOK)
throw new MyError(res);
// do其他
})catch(function(err){
if(err instanceof MyError){
// do something
return false;
}
//处理东西
})

几乎相当(除了做一些,并使用除了这个抛出 MyError 之外的代码。主要区别是当您想连接然后和<$ c $之间的其他 .then(...)调用C>捕获。如果你没有,只要选择你喜欢的东西。


I'm trying to wrap my head around the correct way to indicate a failure within a .then().

If the promise doesn't fail, (I.e. the operation that returns the promise does it' job properly, such as an AJAX request that returns a status 200), but I decide that the result isn't valid, usually I'd do a popup, explaining the issue to the user, and do a "return false;" to exit the method early.

However, 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, and presumably let this get caught by the .catch() that I've chained on.

My concern is that I want to distinguish between an operation within a promise that succeeded, but which I don't like the result of, and a failed operation within a promise.

For example, if I perform an AJAX call and it fails with a 404, that's not really recoverable, so it seems appropriate to reject with a popup saying something like "something went wrong". However, if the AJAX request is successful (returns a status 200), but the response indicates that something isn't right (Like the user didn't fill out a field with a correct value), then I'd like to handle that a certain way, which might involve not just a popup with a message (e.g. maybe DOM manipulations, red text etc, things that I might not want to do if it's a 404).

Below are 2 examples to better explain what I mean. The first being the original implementation with callbacks and the second being with promises (Wrapping the ajax call with the Q promise library to make it a proper promise).

Callback version:

    $.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 version:

    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();

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()?

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

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

I'd like to make sure I'm following best practices as much as possible.

解决方案

TL;DR: You can use rejections for control flow, but in general they are for exceptional cases only


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

Yes.

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

Yes.

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

Not at all. You're not using the Promise constructor (which you don't need, as you already have a promise for the ajax result).

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

Throw different kinds of errors so that you can distinguish them. Give them names, add special properties, do subclassing (in ES6 especially), or just look at the message.

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

Not necessarily. You can do exactly the same as you did without promises - put an if-else in the callback (or an if with an early return if you prefer).

In terms of control flow and their result values,

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

and

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

are pretty much equivalent (except for exceptions in do something and with code other than this throwing MyErrors). The major difference is when you want to chain additional .then(…) invocations between the then and catch. If you don't, just choose whatever you like better.

这篇关于拒绝Javascript承诺和错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆