2011-09-26 56 views
1

好的,这可能是一个愚蠢的问题,但我找不到解决我的问题的方法。我有这样的功能:如何管理Dojo中的ajax响应

function getActivityObj(sysId, date) { 

    var activityObj = dojo.xhrGet({ 
     url: 'calendar/display-subactivities', 
     content: {'sysId': sysId, 'date': date}, 
     handleAs: 'json', 
     load: function(result) { 
      console.log(result); 
     }, 
     error: function(){ 
      alert("error"); 
     } 
    }); 

    var ajaxResponse = activityObj.ioArgs.xhr.response; 
    return ajaxResponse; 
} 

的问题是,我的ajaxResponse变量始终是空的,但如果在Firebug,XHR对象的响应属性不为空。 我会在我的代码中的几个地方使用ajax响应,所以我在做什么错误或什么是更好的方式来调用ajax响应?谢谢。 (对不起我的英文不好)

+1

异步代码要求您稍微小心一点。你需要明确地链接回调(通过load,addCallback或者然后)以便对动作进行排序,并且你必须*不*假定在相应的函数调用返回后IO动作完成。 – hugomg

+1

好吧,xhrGet是异步的(因为你没有明确地将它设置为同步),所以Ajax调用不会直到AFTER函数getActivityObj完成 - 因为JavaScript是单线程的。 'xhrGet'不会执行Ajax调用,它会在函数返回后立即调用Ajax调用。因此,在这个功能块结束之前,'ajaxResponse'总是**总是空的。 –

+0

是的,现在(在阅读答案和评论之后)我终于明白了什么是异步/同步的东西。 – sica07

回答

4

我怀疑变量是空的,当你调用它,因为xhrGet()调用异步的,而结果是不实际可用然而,当你设置,并从你的函数返回。

通过您的萤火查看时,XHR响应已完成,但它只是是不是有你的代码执行时。

xhrGet()返回dojo.Deferred对象。你可以用它来添加一个回调函数,它实际上完成时:

function getActivityObj(sysId, date) { 
    var activityObj = dojo.xhrGet({ 
     url: 'calendar/display-subactivities', 
     content: {'sysId': sysId, 'date': date}, 
     handleAs: 'json', 
     load: function(result) { 
      console.log(result); 
     }, 
     error: function(){ 
      alert("error"); 
     } 
    }); 

    var ajaxResponse; 

    // activityObj is a Deferred 
    activityObj.addCallback(function() { 
     // Use your deferred response 
     ajaxResponse = activityObj.ioArgs.xrh.response; 

     // Now inside this function, do whatever you were going to do 
     // with the xhr return data that you intended to return from 
     // the wrapping function. 
    }); 
} 

我不能肯定是否有包裹xhrGet()呼叫功能,并尝试虽然返回响应的好方法,因为它会如果异步调用,总是被延迟。

如果它是安全的,直到xhrGet()通话实际上已经返回的数据块继续执行,您可以同步调用它。那么你的代码就像没有延迟回调一样工作。相反,您通常可以执行xhrGet()load()函数中返回的数据的任何工作。

var activityObj = dojo.xhrGet({ 
    // Call synchronously 
    sync: true, 
    url: 'calendar/display- subactivities', 
    content: {'sysId': sysId, 'date': date}, 
    // etc... 
+1

我更喜欢使用'.then'承诺方法,而不是来自Deferred的原始'addCallback'等。 '然后'让你用许多简洁的方式编写东西。 – hugomg

+0

@missingno在'.then()'可用(1.4也许?)之前,我开始使用dojo 1.2。我只是没有养成使用它的习惯,因为我没有纯粹在更新的1.5+代码中完成大型项目。 –

+1

在1.5中增加了Promise语义(例如'.then')。实际上,您可以使用'addCallback','addErrback'等链接回调,尽管它们的行为有所不同,区别很重要。国际海事组织,最好学习未来承诺的“新”方式。另见:http://www.sitepen.com/blog/2010/05/03/robust-promises-with-dojo-deferred-1-5/和http://dojotoolkit.org/documentation/tutorials/1.6/承诺/ –