[英]How to dodge jQuery promises completely when chaining two async jQuery functions?
我見過很多關於新EMCA承諾的教程,主張避免jQuery庫中的“promises”。 他們通常說你可以通過做這樣的事情來躲避他們:
Promise.resolve($.getJSON(url, params)); // voila! the jQuery promise is "gone"!
但是,當我必須將兩個異步jQuery函數鏈接在一起時,這並不真正起作用。 如何在不使用jQuery的then()或.when()的情況下將兩個getJSON調用(第二個調用依賴於第一個調用)鏈接在一起?
相反,我只想使用Promise.all等。
我認為一個類似的問題問題是交叉jquery和EMCA的承諾?
JavaScript承諾是可互操作的 。 您可以根據需要混合使用它們,所有適當的庫1和本機承諾都可以接受來自任何地方 3的任何實現的thenables 2 。 如果出現異物,他們就會Promise.resolve
進行Promise.resolve
。
所以通常你會編寫你的代碼,好像它們都使用了相同的promise實現,它只是起作用 。
但是,現在您要確保所有.then
方法調用都使用您喜歡的實現; 或者您想使用非標准方法或功能? 為此,您必須顯式地轉換所有 直接調用方法的 promise - 而不是其他任何東西。
一些例子:
Promise.all([$.ajax(…), $.ajax(…)]).then(…); // just works!
$.ajax(…) // a jQuery promise
.then(…) // so this would be jQuery `then`, which we don't want.
Promise.resolve($.ajax(…)) // explicit cast
.then(function(data) { // native `then`
return $.ajax(…); // just works!
}) // returns a native promise still
.catch(…) // so we can use its features
1:是的,直到3.0版本,jQuery才是其中之一
2: 盡管如此 ,所有jQuery延遲和承諾都是這樣的
3:真的到處都是你期望的承諾,在Promise.resolve
, then
回調返回值, Promise.all
參數,......
你可以采用兩種方法中的任何一種......
轉換然后結合:
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 promises解決時解析,或者當其中一個promise失敗時被拒絕。
但是,您可能對兩個getJSON()
調用的結果感興趣,並且jQuery在這方面很尷尬。 jQuery的jqXHR承諾將多個參數傳遞給它們的成功和錯誤回調,而ES6承諾只接受一個; 其余的將被忽視。 幸運的是,將多個參數捆綁在一起以制作單個對象相當簡單。 這必須在轉換到ES6之前在jQuery中完成。
“convert then combine”代碼擴展如下:
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中)到數組。
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
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.