当前位置: 首页 > 面试题库 >

拒绝Javascript承诺和错误处理

丰辰沛
2023-03-14
问题内容

我正在尝试用正确的方法表示正确的方法,以指示内发生故障.then()

如果诺言没有失败,(即返回诺言的操作是否正常工作,例如返回状态200的AJAX请求),但是我认为结果无效,通常我会这样做弹出窗口,向用户说明问题,然后执行“返回假”;尽早退出该方法。

但是,有了承诺,如果我想从.then()内部做类似的事情,我就被引导去相信我应该做的是抛出一个错误,而应该让它被.catch()抓住。 ),我已经锁定了。

我担心的是,我想区分承诺中成功但不满意结果的操作与承诺中失败的操作。

例如,如果我执行一个AJAX调用,但失败并显示404,则该错误实际上无法恢复,因此似乎应该通过弹出窗口拒绝诸如“出事了”之类的消息来拒绝。

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

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

第一个是带有回调的原始实现,第二个是带有promise(将Ajax调用与Q promise库包装在一起以使其成为正确的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");

});

承诺版本:

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

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

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

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


问题答案:

TL; DR:可以
将拒绝用于控制流,但通常,它们仅用于特殊情况

在Promise版本中,如果请求返回404,它将立即以.catch()结尾,对吗?

是。

如果data.IsSuccessful == 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
})

.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此throw之外MyError的代码中的异常以及带有此类异常的代码)。主要区别在于何时要.then(…)then和之间链接其他调用catch。如果不这样做,请选择更喜欢的选项。



 类似资料:
  • 问题内容: 在我的服务器应用程序中,当用户无权访问端点时,我想返回“禁止”值。 为此,我创建了一个被拒绝的重用承诺: 然后在应用程序中的其他位置: 但是,当我启动我的应用程序时,会收到警告 我怎么能告诉Node这个Promise可以解决呢? 问题答案: 我创建了被拒绝的重用承诺 好吧,仅创建一个可重用的函数可能会容易得多: 每次调用该错误时,也会为该错误提供适当的堆栈跟踪。 我怎么能告诉Node这

  • 问题内容: 我已经阅读了几篇有关该主题的文章,但是我仍然不清楚是否与抛出错误之间有区别。例如, 使用Promise.reject 使用抛出 我倾向于仅使用它,因为它更短,但我想知道一个相对于另一个是否有任何优势。 问题答案: 使用一个相对于另一个没有优势,但是,在特定情况下无法使用。但是,这些情况可以解决。 每当您进入promise回调时,都可以使用。但是,如果您在任何其他异步回调中,则必须使用。

  • 问题内容: 我在理解为什么拒绝不通过承诺链传递时遇到问题,我希望有人能够帮助我理解原因。对我来说,将功能附加到承诺链上意味着我有意要实现的原始承诺。很难解释,所以让我先显示我的问题的代码示例。(注意:此示例使用的是Node和延迟的节点模块。我使用Dojo 1.8.3对此进行了测试,并得到了相同的结果) 运行此操作的结果是以下输出: 好吧,对我来说,这个结果没有意义。通过附加到这个承诺链,每个人都暗

  • 问题内容: 我需要创建链式承诺: 如果我将errorCallback放在第一个中,则第二个将被解析,并调用其successCallback。但是,如果我删除了,那么第二个承诺将被拒绝。 根据Angular JS的文档,传播拒绝的唯一方法是返回并且它看起来并不明显,尤其是因为即使不需要它,我也必须注入服务。 也可以通过在中引发异常来完成此操作,但是它将异常跟踪写入控制台,这不好。 还有另一种选择可以

  • 问题内容: 当我使用Node运行此代码时,它会在控制台中引发错误(甚至首先显示文本)。 但是,当我将方法链接到方法时,错误消失了: 难道第一个代码不应该处理拒绝吗? 我还尝试了Chrome中的第一个代码,当我在新标签页(或google.com)中打开检查器时,该代码就可以使用。如果我在其他任何页面中,则会引发异常。有什么解释吗?这对我来说真的很奇怪! 问题答案: 为了被视为已处理,被拒绝的诺言应与

  • 问题内容: 在下面的代码中: 从api 使用(in )和使用抛出错误(in )有什么区别? 完全一样吗? 如果相同,为什么我们需要回调呢? 问题答案: 从api 使用(in )和使用抛出错误(in )有什么区别? 是的,当是回调时,您不能异步使用。例如,一些超时: 完全一样吗? 不,至少在您的语句后面跟随其他代码时才不会。立即完成解析程序功能,同时调用继续正常执行-在“标记”了承诺被拒绝之后。 此