为什么我的Jquery ajax成功处理程序是用数组调用的(而不是响应对象)

时间:2013-12-13 13:18:26

标签: ajax jquery jquery-deferred google-spreadsheet-api

我有一个功能,可以对谷歌电子表格API进行两次休息调用。我使用$ .when来确保在处理第二次调用的数据之前,第一次调用的数据处理完毕。

问题是第一个ajax处理程序(getRealNames)接收一个javascript对象作为其参数,但是第二个处理程序(displayTeams)接收一个数组,第0个元素是我期望得到的对象。

为什么一个人获得一个对象而另一个获得一个数组?他们正在呼唤同样的休息api。 直到我重构代码以使用延迟而不是回调嵌套,数组才出现。所以我认为这是一个jquery问题,而不是一个电子表格API问题。

(参见下面的屏幕截图,我已经控制了。两个处理程序收到的参数

//this is the function generating the REST requests, I just put it in for completeness
function getWorkSheet(doc_key,sheet){
  return $.get('https://spreadsheets.google.com/feeds/list/'+
    doc_key+'/'+sheet+
    '/private/full?alt=json&access_token=' 
    + googleAPItoken)
    .fail(function(){
      alert("failed to get google doc:"+doc_key+" ,sheet: "+sheet);
    });

  }

 function getRWMTeams() {
    var nameQuery=getWorkSheet(doc_key,1);
    nameQuery.done(getRealNames);

    var repoQuery=getWorkSheet(doc_key,2);

    //the deferred:'namesProcessed' is resolved in getRealNames
    $.when(repoQuery,namesProcessed)
      .done(displayTeams);

  }

enter image description here

3 个答案:

答案 0 :(得分:2)

最后,仔细阅读api doc(http://api.jquery.com/jQuery.when/)会在代码示例中显示以下注释;

// 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 ]

我读过第一条评论,并假设参数只是返回数据。第二条评论揭示了我的问题的根源。

答案 1 :(得分:1)

尽管这是一个陈旧的回答问题,但在jQuery进入Promise / A ++时代之前(2015年某个时候预计),它应该得到一个更完整的答案。

与其他承诺库不同,jQuery承诺可以通过多个值来解决。这使jQuery.when()的生活有些尴尬。

文档说:

  

传递给doneCallbacks的参数为每个Deferreds提供已解析的值,并匹配Deferreds传递给jQuery.when()的顺序。

继续解释doneCallback参数对不同数量的已解析值的行为 - 这就是它有点疯狂的地方:

  • 无值:相应的参数将是 undefined
  • 单个值:相应的参数将保存该值
  • 多个值:相应的参数将是这些值的数组

您所看到的是第三种情况 - jQuery.ajax() - datatextStatusjqXHR返回的三个值 - 捆绑在一个数组中。当直接使用jqXHR promise 时,这是不可避免的。

但是,有一种解决方法。如果您安排getRealNames()包含链式.then(),则可以放弃textStatusXHR,并返回data的承诺 - 并且因此,给出上述单值行为。例如:

function getRealNames() {
    return $.ajax(...)
        .then(function(data, textStatus, jqXHR) {
            return data;
        });
}

您需要做的就是,但您的getRWMTeams()功能也可以整理,如下所示:

function getRWMTeams() {
    var repoQuery = getWorkSheet(doc_key, 2);
    var namesProcessed = getWorkSheet(doc_key, 1).then(getRealNames);
    return $.when(repoQuery, namesProcessed).then(displayTeams);
}

function getRWMTeams() {
    return $.when(
        getWorkSheet(doc_key, 2), 
        getWorkSheet(doc_key, 1).then(getRealNames)
    ).then(displayTeams);
}

答案 2 :(得分:0)

感谢您提出这个问题,并提供答案。我一直遇到完全相同的问题,试图理解“作为数组的论点”背后的原因是一个挑战。

现在我理解为什么参数是数组,我注意到只有第一个参数是数组。第二个参数只包含数据(来自已解析的延迟)。你也注意到了吗?这是一个截图来解释更多:

'fields'和'defn'是我在完成回调中的参数。一个是数组,另一个是对象。我很想知道你对此的看法。

Chrome console showing the arguments