我正在尝试编写一个通用代码来获取promises的结果。请参阅示例代码。
https://jsfiddle.net/f995r4ue/
var testUri = 'https://fiddle.jshell.net/robots.txt';
var promises = [];
promises.push($.get(testUri));
$.when.apply($, promises).then(function() {
// arguments is array of objects
console.log(arguments);
});
var promises = [];
promises.push($.get(testUri));
promises.push($.get(testUri));
$.when.apply($, promises).then(function() {
// arguments is array of arrays
console.log(arguments);
});
如代码中所述,如果输入数组只有一个promise,则结果结构与其他情况不同。
我做错了吗?
答案 0 :(得分:1)
这是jQuery Ajax承诺工作的疯狂方式以及jQuery决定如何实现$.when()
的副产品。这有点奇怪的行为偶尔有用,但不足以经常让你疯狂。行为的不一致性不是一个好的基本设计,我相信jQuery计划在jQuery 3.0中清除它,因为它们应该与ES6标准的promise规范兼容(这种方式并不奇怪)。
这是发生了什么。一个jQuery Ajax承诺解析了三个值(完全不符合promise)。如果您只将其中一个承诺传递给$.when()
,那么$.when()
直接通过该承诺(根据文档,它甚至不会创建新承诺)。因此,当该Ajax承诺解析并调用它的.then()
处理程序时,它将以原始承诺的方式调用.then()
处理程序,该处理程序具有三个单独的参数。如果在这种情况下查看arguments
附加到.then()
处理程序的$.when()
对象,您将看到三个不连续的参数。
但是,如果您将多个承诺传递给$.when()
,那么它会创建一个新的超集承诺,监控您传递的所有承诺。如果每个基础promise都使用多个值解析,则该超集promise将把每个单独的promise的参数放入其自己的数组中,并将每个单独的数组作为单独的参数传递给.then()
处理程序。如果查看arguments
对象,您将看到一个数组数组。如果每个潜在的承诺只用一个值解决,那么每个参数就只是那个值 - 另一个不一致点。
我期待jQuery 3.0说它将遵循承诺规范,它将停止做这种奇怪的事情。
以下是jQuery doc中的示例:
// single promise passed to $.when()
// arguments to `$.when()` are identical to what that single promise would
// have sent to its .then() handler which for a jQuery Ajax
// function is three separate arguments
$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {
alert( jqXHR.status ); // Alerts 200
});
// multiple promises passed to $.when()
// Each argument to .then() is an array of arguments
$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).then(function( a1, a2 ) {
// a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
// Each argument is an array with the following structure: [ data, statusText, jqXHR ]
var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
if ( /Whip It/.test( data ) ) {
alert( "We got what we came for!" );
}
});
所以,是的,行为是一致的。如果您不知道期望有多少参数,则必须测试您决定如何处理它的类型。
所以,这里发生的非标准和不一致的事情是:
$.when()
的行为会有所不同。$.when()
的行为会有所不同。 ES6承诺世界要简单得多,因为承诺永远不会解决多个值。如果程序员想要回传多个值,那么你就可以解决一个数组或一个对象(就promise而言仍然是一个单独的值)并且jQuery正在做的这些不一致的恶作剧都不能完成。你总是知道你将在Promise.all()
得到什么 - 你总能得到一系列结果。
答案 1 :(得分:-1)
Multiple返回2的原因是数组中有2个元素(2个push操作的结果)。每个数组元素(promises [0]和promises [1])包含3个与Single实例相等的元素。