使用一个或多个jQuery promises

时间:2016-10-19 23:57:55

标签: javascript jquery promise

我正在进行一次或多次REST / ajax调用以验证一些用户信息。其余的电话工作正常,信息又回来了。我面临的问题不在于代码的那部分,看起来像这样。

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?

2 个答案:

答案 0 :(得分:3)

  

我觉得很奇怪,返回的结构会像那样改变。

是的,jQuery在这里非常不一致。当您将单个参数传递给$.when时,它会尝试将其转换为承诺,当您传递多个参数时,它会突然尝试等待所有这些参数并合并其结果。现在抛出jQuery promises可以解决多个值(参数)和add a special case for that

所以我可以推荐两种解决方案:

  • 完全删除$.when并使用Promise.all代替它:

    var promises = [];
    for (var p of recipients) {
        …
        promises.push( $.ajax({…}));
    }
    
    Promise.all(promises)
    .then(function(results) {
         console.log(results);
    })
    
  • 让每个承诺只用一个值解决(与{3}解析为3不同),这样它们就不会被包裹在数组中,而$.ajax()会产生一致结果无论参数数量如何:

    $.when

答案 1 :(得分:1)

此功能似乎正在当前documented。当您将多个延迟传递给tabBarController.tabBar.addSubView(yourButton) 时,它会创建一个新的$.when对象,该对象将使用传入的延迟的每个结果的结果进行解析。当你只传入一个时,它会返回你传入的延迟,因此只返回结果而不是结果数组。

我不确定它是否比您当前的解决方案更好,但您可以通过在评估结果时跳过“跳过”延迟来强制它总是有多个延迟。

Promise

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