我已经看过许多有关新EMCA的教程,这些教程承诺提倡在jQuery库中避免“承诺”。他们通常说您可以通过执行以下操作来躲避他们:
Promise.resolve($.getJSON(url, params)); // voila! the jQuery promise is "gone"!
但是,当我必须将两个异步jQuery函数链接在一起时,这实际上不起作用。我如何将两个getJSON调用(第二个调用取决于第一个调用)链接在一起而不使用jQuery的then()或.when()?
相反,我只想使用Promise.all等。
我认为类似的问题是交错jquery和EMCA Promise?
您可以采用两种方法之一…
转换然后合并:
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 Promise,p3当两个jQuery Promise 都解决时,它就会解决;当其中一个Promise失败时,它就会被拒绝。
p3
但是,您可能对这两个getJSON()调用的结果感兴趣,并且jQuery在这方面很尴尬。jQuery的jqXHR Promise将 多个 参数传递给它们的成功和错误回调,而ES6 Promise只接受一个。其余的将被忽略。幸运的是,将多个参数捆绑在一起以创建单个对象非常简单。必须先在jQuery中完成,然后再转换为ES6。
getJSON()
“转换然后合并”代码扩展如下:
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列表,列表本身需要转换(仍在jQuery中)为数组。
arguments
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 } );