ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 从JS中被拒绝的承诺中恢复

2019-06-28 12:21:43  阅读:184  来源: 互联网

标签:jquery javascript deferred


我正在使用本机承诺(主要是)并尝试从错误中恢复并继续执行promise链.

实际上,我这样做:

> REST查询以查看ID是否存在.请注意,这将返回延迟的jquery.
> .then(成功意味着ID存在,所以失败并停止)
    (fail表示ID不存在,因此继续创建ID)
> .then(创建ID记录并发送到服务器)

我从被拒绝的函数返回一个Promise.resolve(),它应该导致下一个.then的成功部分执行.它不是.我在Chrome和Safari上试过这个.

请注意,第一个promise实际上是一个延迟的查询,但根据此页面(http://api.jquery.com/deferred.then/),deferred.then()返回一个promise对象.因此,添加额外的.then应该转换为原生承诺.

为了更清楚 – 这是伪代码:

promise = $.ajax(url);
promise = promise.then();  // convert to promise 
promise.then(function() { cleanup(); return Promise.reject(); },
    function(err) { return Promise.resolve(); });
.then(function() { createIdentityDetails(); });
.then(function() { sendIdentityDetails(); });

请注意,当ajax返回成功时我想要失败,我想
当ajax调用失败时继续处理.

会发生的是,所有后续部分的FAIL功能都会执行.也就是说,我的返回Promise.resolve()不起作用 – 这是(我认为)违反规范.

我很感激有关如何处理和从长期承诺链中的错误中恢复的任何反馈.

非常感谢您提供的任何建议.

附:创建和收集完整的身份信息非常耗时,因此如果ID存在,我不想这样做.因此我想先检查并快速失败.

p.p.s我真的很喜欢promises解开这些深度嵌套的异步回调链的方式.

解决方法:

假设createIdentityDetails()和sendIdentityDetails()是promise – 返回异步函数……

如果我们在问题中看到的是整个承诺链,那么处理错误条件很简单.没有必要将成功转化为失败或失败转化为成功,或从一种承诺转变为另一种承诺.

$.ajax(url).then(function() {
    cleanup();
}, function(err) {
    createIdentityDetails()
    .then(sendIdentityDetails);
});

无论createIdentityDetails()jQuery或非jQuery返回的promise类型如何,这都将起作用.

但是,如果还有更多内容,例如呼叫者功能需要被告知结果,那么您需要做更多,这取决于您希望如何报告可能的结果.

报告’ID已存在’为失败,’新ID已创建’为成功

这就是问题所暗示的

function foo() {
    return $.ajax(url).then(function() {
        cleanup();
        return $.Deferred().reject('failure: ID already exists');
    }, function(err) {
        return createIdentityDetails()
        .then(sendIdentityDetails)
        .then(function() {
            return $.when('success: new ID created');
        });
    });
}

将两种类型的结果报告为成功

这似乎更合理,因为处理错误将被报告为成功.只会报告不可预测的未处理错误.

function foo() {
    return $.ajax(url).then(function() {
        cleanup();
        return 'success: ID already exists';
    }, function(err) {
        return createIdentityDetails()
        .then(sendIdentityDetails)
        .then(function() {
            return $.when('success: new ID created');
        });
    });
}

无论采用哪种报告策略,重要的是createIdentityDetails()返回的承诺类型.作为链中的第一个承诺,它决定了它的链式.thens的行为.

>如果createIdentityDetails()返回本机ES6承诺,那么不用担心,大多数风格的承诺,甚至jQuery,都会被同化.
>如果createIdentityDetails()返回一个jQuery promise,那么只有jQuery promises才会被同化.因此,sendIdentityDetails()还必须返回一个jQuery承诺(或者必须使用$.Deferred(…)重新转换为jQuery的ES6承诺),以及最终成功转换器(如上所述).

您可以通过这两种方式看到混合jQuery和ES6承诺的效果here.第一个警报是由第二个代码块生成的,并不是预期的.第二个警报由第一个块生成,并正确地给出结果98 1 1 = 100.

标签:jquery,javascript,deferred
来源: https://codeday.me/bug/20190628/1315633.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有