使用1个或更多jQuery承诺
我正在进行一次或多次REST / ajax调用以validation一些用户信息。 其余的电话工作正常,信息又回来了。 我面临的问题不在于代码的那部分,它看起来像这样。
function ensureUsers(recipients){ var promises = []; for(var key in recipients){ var payload = {'property':recipients[key]}; promises.push( $.ajax({...})); } return $.when.apply($,promises); } .... ensureUsers(users) // users is an array of 1 or more users .done(function(){ console.log(arguments); )}
如果初始数组中有多个用户,那么我的.done
代码中的参数结构如下:
[[Object,"success",Object],[Object,"success",Object]...]
然后,我可以迭代每个结果,检查状态,然后继续。
但是如果初始数组中只有一个用户,那么.done
会得到如下参数:
[Object,"success",Object]
我觉得奇怪的是返回的结构会像那样改变。 我找不到任何关于这个特定问题的信息,所以我一起解决了一个问题
var promises = Array.prototype.slice.call(arguments); if(!Array.isArray(promises[0])){ promises = [promises]; }
这真的是我能想到的最好的吗? 或者是否有更好的方法来处理来自jQuery中的一个或多个ajax调用的返回promise?
我觉得奇怪的是返回的结构会像那样改变。
是的,jQuery在这里非常不一致。 当你将一个参数传递给$.when
,它会尝试将它转换为一个promise,当你传递多个它时,它突然试图等待所有这些并合并它们的结果。 现在抛出jQuery promises可以解决多个值(参数),并为此添加一个特例 。
所以我可以推荐两种解决方案:
-
完全丢弃
$.when
然后使用Promise.all
而不是它:var promises = []; for (var p of recipients) { … promises.push( $.ajax({…})); } Promise.all(promises) .then(function(results) { console.log(results); })
-
使每个promise只用一个值解决(不像
$.ajax()
解析为3),这样它们就不会被包装在数组中,并且$.when
将产生一致的结果,无论参数的数量如何:var promises = []; for (var p of recipients) { … promises.push( $.ajax({…}).then(function(data, textStatus, jqXHR) { return data; }) ); } $.when.apply($, promises) .then(function() { console.log(arguments); })
看来此function正如当前记录的那样工作。 如果有多个延迟传递给$.when
它创建一个新的Promise
对象时,该对象将使用传入的延迟的每个结果的结果进行解析。 当您只传入一个时,它会返回您传入的延迟,因此只返回结果而不是结果数组。
我不确定它是否比你当前的解决方案更好,但你可以通过在评估结果时跳过一个“假”推迟来强制它总是有多个延迟。
IE
function ensureUsers(recipients){ var promises = [$.Deferred().resolve()]; for(var key in recipients){ var payload = {'property':recipients[key]}; promises.push( $.ajax({...})); } return $.when.apply($,promises); }
你也可能做到这一点,所以延迟的占位符解析的结构与你在实际结果中所期望的结构相同,所以看起来第一个响应总是成功。