如何在链接两个异步jQuery函数时完全避开jQuery promises? [英] How to dodge jQuery promises completely when chaining two async jQuery functions?

查看:112
本文介绍了如何在链接两个异步jQuery函数时完全避开jQuery promises?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到许多有关新EMCA承诺的教程,主张避免在jQuery库中使用promises。他们通常会说你可以通过这样的方式躲闪他们:

I've seen many tutorials on the new EMCA promises advocating avoidance of the "promises" in the jQuery library. They usually say that you can dodge them by doing something like this:

Promise.resolve($.getJSON(url, params)); // voila!  the jQuery promise is "gone"!

然而,当我必须将两个异步jQuery函数链接在一起时,这不起作用。如何在不使用jQuery的then()或.when()的情况下将两个getJSON调用(第二个调用依赖于第一个调用)链接在一起?

However, this doesn't really work when I have to chain two async jQuery functions together. How would I chain two getJSON calls (where the second call depends on the first) together without using jQuery's then() or .when()?

相反,我只想要使用Promise.all等。

Instead, I only want to use Promise.all etc.

我认为类似的问题是交错jquery和EMCA的承诺?

I think a similar question problem would be interleaving jquery and EMCA promises?

推荐答案

您可以采用两种方法中的任何一种......

You can adopt either of two approaches ...

转换然后合并:

var p1 = Promise.resolve($.getJSON(url_1, params_1)); // voila 1!
var p2 = Promise.resolve($.getJSON(url_2, params_2)); // voila 2!
var p3 = Promise.all([p1, p2]).then(...);

合并然后转换:

var p1 = $.getJSON(url_1, params_1);
var p2 = $.getJSON(url_2, params_2);
var p3 = Promise.resolve($.when(p1, p2)).then(...); // voila 1 and 2!

直截了当,任何一种方法都会给你一个原生的ES6承诺, p3 ,当jQuery promise都解析时解析,或者当其中一个promise失败时被拒绝。

Straightforwardly, either approach will give you a native ES6 promise, p3, that resolves when both the jQuery promises resolve, or is rejected when either one of the promises fails.

但是,您可能对两个 getJSON()调用的结果感兴趣,并且jQuery很尴尬对此。 jQuery的jqXHR承诺将多个参数传递给他们的成功和错误回调,而ES6承诺只接受一个;其余的
将被忽视。幸运的是,将多个参数捆绑在一起以制作单个对象相当简单。这必须在转换为ES6之前在jQuery中完成。

However, you are probably interested in the results of the two getJSON() calls, and jQuery is awkward in this regard. jQuery's jqXHR promises pass multiple parameters to their success and error callbacks, whereas an ES6 promise will accept just one; the rest will be disregarded. Fortunately, it's fairly simple to bundle the multiple params together to make a single object. This has to be done in jQuery prior to conversion to ES6.

convert then combine代码扩展如下:

The "convert then combine" code expands as follows :

var p1 = Promise.resolve($.getJSON(url_1, params_1).then(
    function(data, textStatus, jqXHR) {
        return { data:data, textStatus:textStatus, jqXHR:jqXHR };
    },
    function(jqXHR, textStatus, errorThrown) {
        return { jqXHR:jqXHR, textStatus:textStatus, errorThrown:errorThrown };
    }
));
var p2 = Promise.resolve($.getJSON(url_2, params_2).then(
    function(data, textStatus, jqXHR) {
        return { data:data, textStatus:textStatus, jqXHR:jqXHR };
    },
    function(jqXHR, textStatus, errorThrown) {
        return { errorThrown:errorThrown, textStatus:textStatus, jqXHR:jqXHR };
    }
));
var p3 = Promise.all([p1, p2]).then(
    function(results) {
        // results[0] will be an object with properties .data, .textStatus, .jqXHR 
        // results[1] will be an object with properties .data, .textStatus, .jqXHR 
    },
    function(rejectVal) {
        // rejectVal will be an object with properties .errorThrown, .textStatus, .jqXHR
    }
);

合并然后转换方法稍微复杂一点,因为合并后的结果(在jQuery中)显示为 arguments list,它本身需要转换(仍然在jQuery中)到一个数组。

The "combine then convert" approach is slightly trickier as the combined results appear (in jQuery) as an arguments list, which itself needs to be converted (still in jQuery) to an Array.

var p1 = $.getJSON(url_1, params_1).then(
    function(data, textStatus, jqXHR) { 
        return { data:data, textStatus:textStatus, jqXHR:jqXHR }; 
    },
    function(jqXHR, textStatus, errorThrown) { 
        return { errorThrown:errorThrown, textStatus:textStatus, jqXHR:jqXHR }; 
    }
);
var p2 = $.getJSON(url_2, params_2).then(
    function(data, textStatus, jqXHR) { 
        return { data:data, textStatus:textStatus, jqXHR:jqXHR };
    },
    function(jqXHR, textStatus, errorThrown) { 
        return { errorThrown:errorThrown, textStatus:textStatus, jqXHR:jqXHR }; 
    }
);
var p3 = Promise.resolve($.when(p1, p2).then(function() {
    return [].slice.call(arguments);// <<< convert arguments list to Array
})).then(
    function(results) { 
        // results[0] will be an object with properties .data, .textStatus, .jqXHR
        // results[1] will be an object with properties .data, .textStatus, .jqXHR
    },
    function(rejectVal) { 
        // rejectVal will be an object with properties .errorThrown, .textStatus, .jqXHR
    }
);

DEMO:已解决

DEMO: resolved

DEMO:拒绝

DEMO: rejected

这篇关于如何在链接两个异步jQuery函数时完全避开jQuery promises?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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