0

我知道这是一个函数 101 类型的问题,但我们都需要学习。

我有一个 AJAX 调用函数(下面的代码段)存储在我自己的库 .js 文件中,它返回对象中的许多变量。

function getMyDetails(){
//does processing

    return { 
        firstName: firstName,
        office: office, 
        manager: manager, 
        workphone: workphone, 
        isAdministrator: isAdministrator 
        }
   }

在我网页上的脚本中,我调用这个函数如下:

$userDetails = getMyDetails();

然后尝试像这样引用对象中的项目:

$userFirstName = $userDetails.firstName;

但是在运行脚本时,我在控制台中返回“$userDetails is undefined”错误。

问:我应该如何引用 getMyDetails() 函数以使我能够在我的页面中公开返回的变量?

更新:

我的完整功能代码在这里。为了抽象出这个问题,我没有在前面包含它,因为我正在处理一个 SharePoint 网站并使用SPServices库,因此我的 AJAX 调用被包装在一个单独的库函数中

function getMyDetails(){
var $userName = $().SPServices.SPGetCurrentUser({fieldName: "Name", debug: true });
    $().SPServices({
      operation: "GetUserProfileByName",
      async: false,
      AccountName: $userName,
      completefunc: function (xData, Status) {
        var firstName = getUPValue(xData.responseXML, "FirstName");
        var office = getUPValue(xData.responseXML, "Office");
        var manager = getUPValue(xData.responseXML, "Manager");
        var workphone = getUPValue(xData.responseXML, "WorkPhone");
        var SharepointAdministrator = getUPValue(xData.responseXML, "SharepointAdministrator");
        alert("What I've got is " + firstName +" and " + office +" and " +  manager +" and " + workphone  +" and " + SharepointAdministrator);

        return { 
            firstName: firstName,
            office: office, 
            manager: manager, 
            workphone: workphone, 
            SharepointAdministrator: SharepointAdministrator 
            }
       }
    });

    function getUPValue(x, p) {
      var thisValue = $(x).SPFilterNode("PropertyData").filter(function() {
        return $(this).find("Name").text() == p;
      }).find("Values").text();
      return thisValue;
    }
}

虽然我承认这 [通常] 不是好的做法,但我正在同步进行 AJAX 调用(使用 'async: false' 选项),并且在任何进一步的下游处理之前,所有变量都在我的警报语句中正确填充 [似乎] 发生。

4

2 回答 2

2

您正在进行 ajax 调用,但您没有捕获返回的结果!

有不止一种方法可以做到这一点,试试这个:

function getMyDetails(){
var myDetails;
var $userName = $().SPServices.SPGetCurrentUser({fieldName: "Name", debug: true });
$().SPServices({
  operation: "GetUserProfileByName",
  async: false,
  AccountName: $userName,
  completefunc: function (xData, Status) {
    var firstName = getUPValue(xData.responseXML, "FirstName");
    var office = getUPValue(xData.responseXML, "Office");
    var manager = getUPValue(xData.responseXML, "Manager");
    var workphone = getUPValue(xData.responseXML, "WorkPhone");
    var SharepointAdministrator = getUPValue(xData.responseXML, "SharepointAdministrator");
    alert("What I've got is " + firstName +" and " + office +" and " +  manager +" and " + workphone  +" and " + SharepointAdministrator);

    myDetails = { 
        firstName: firstName,
        office: office, 
        manager: manager, 
        workphone: workphone, 
        SharepointAdministrator: SharepointAdministrator 
        };
   }
});

return myDetails;

function getUPValue(x, p) {
  var thisValue = $(x).SPFilterNode("PropertyData").filter(function() {
    return $(this).find("Name").text() == p;
  }).find("Values").text();
  return thisValue;
}
}
于 2013-11-01T01:58:28.717 回答
1

如果此处理中有异步 ajax 函数:

function getMyDetails(){
//does processing including async ajax calls

    return { 
        firstName: firstName,
        office: office, 
        manager: manager, 
        workphone: workphone, 
        isAdministrator: isAdministrator 
        }
   }

然后,问题是 ajax 调用的异步性质意味着它直到某个时间后才会完成。因此,您不能像现在这样使用正常的顺序编程,因为 ajax 调用在返回时尚未完成getMyDetails(),因此所有数据值仍然未定义。

相反,您必须更改代码的工作流程。您不能只为getMyDetails()您所拥有的功能创建一个功能。我不知道您要执行的操作的整体结构,但您可能需要将使用 ajax 调用结果的逻辑放入一个回调函数中,该回调函数在 ajax 函数完成时被调用。

这可能看起来像这样:

function getMyDetails(callback){
//does processing including ajax calls

   // inside the ajax success handler, put this:
   callback({ 
        firstName: firstName,
        office: office, 
        manager: manager, 
        workphone: workphone, 
        isAdministrator: isAdministrator 
        });
   }

然后,当你想使用它时,你可以这样使用它:

getMyDetails(function(data) {
    // code goes here that uses data.firstName, data.office, data.manager, etc...
});

然后,所有使用细节的代码都必须放入该回调函数中。为了使用异步 ajax 调用,您不能像以前那样只进行正常的顺序编程。

其他相关答案:

如何调用异步 JavaScript 函数并阻止原始调用者

如何从使用 ajax 的 javascript 函数中获取价值

异步请求后数组中未定义的索引

JavaScript 中的“递归 AJAX 回调”如何工作?

为什么我的 jQuery AJAX 函数总是返回 false?

如何访问块内的变量

于 2013-11-01T01:20:33.157 回答