使用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); } 

你也可能做到这一点,所以延迟的占位符解析的结构与你在实际结果中所期望的结构相同,所以看起来第一个响应总是成功。