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

为什么使用数组(而不是响应对象)调用Jquery ajax成功处理程序,ajax,jquery,jquery-deferred,google-spreadsheet-api,Ajax,Jquery,Jquery Deferred,Google Spreadsheet Api,我有一个函数,可以对google spreadsheetAPI进行两次rest调用。在处理第二次调用的数据之前,我使用$.when来确保第一次调用的数据是process 问题在于,第一个ajax处理程序(getRealNames)接收一个javascript对象作为其参数,而第二个处理程序(displayTeams)接收一个数组,第0个元素是我期望得到的对象 为什么一个得到一个对象,另一个得到一个数组?他们正在调用相同的RESTAPI。 直到我重构代码以使用延迟而不是回调嵌套,数组才出现。所以我

我有一个函数,可以对google spreadsheetAPI进行两次rest调用。在处理第二次调用的数据之前,我使用$.when来确保第一次调用的数据是process

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

为什么一个得到一个对象,另一个得到一个数组?他们正在调用相同的RESTAPI。 直到我重构代码以使用延迟而不是回调嵌套,数组才出现。所以我认为这是一个jquery问题,而不是spreadsheetAPI问题

(请参阅下面的屏幕截图,我已经将控制台中两个处理程序接收到的参数记录下来

//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);

  }

最后,仔细阅读api文档()后,在代码示例中显示了以下注释:

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

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

谢谢你提出这个问题,也提供了答案。我一直遇到完全相同的问题,并试图理解“参数是数组”背后的原因这是一个挑战

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

“fields”和“defn”是我在done回调中的参数。一个是数组,另一个是对象。我想知道你对此的想法


尽管这是一个老生常谈的问题,但在jQuery进入承诺/a++时代(预计2015年某个时候)之前,它应该得到一个更完整的答案

与其他promise LIB不同,jQuery promises可以用多个值来解析。这使得
jQuery.when()
的生活有些尴尬

文件说:

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

接着解释了doneCallback参数对于不同数量的解析值的行为-这就是它变得有点疯狂的地方:

  • 无值:相应的参数将未定义
  • 单个值:相应的参数将保存该值
  • 多个值:相应的参数将是这些值的数组
您看到的是第三种情况—由
jQuery.ajax()
-
data
textStatus
jqXHR
绑定到一个数组中返回的三个值。当直接使用jqXHR承诺时,这是不可避免的

但是,有一个解决方法。如果您安排
getRealNames()
包含一个链接的
。然后()
,可以使其放弃
textStatus
XHR
,并返回一个只包含
数据的承诺,从而给出上面描述的单个值行为。例如:

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


可能是因为您将两个延迟对象传递给whenI,我注意到在作为$.when()参数提供的两个方法中,只有一个方法实际使用$.get()进行ajax调用。这是因为我编写代码的方式。另一个方法只使用$.deferred()并返回承诺(我的代码立即解决了这个问题)。也许只有在生成实际的xhr时,回调参数才是数组(包含xhr详细信息)才有意义。
function getRWMTeams() {
    return $.when(
        getWorkSheet(doc_key, 2), 
        getWorkSheet(doc_key, 1).then(getRealNames)
    ).then(displayTeams);
}