簡體   English   中英

如何在鏈接兩個異步jQuery函數時完全避開jQuery promises?

[英]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.resolvethen回調返回值, 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
    }
);

演示:解決了

DEMO:被拒絕了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM