使函数等到使用jQuery完成AJAX调用

我试图用JavaScript开发一个类,我可以使用它来访问由AJAX请求轻松收集的数据量。 唯一的问题是我需要在AJAX调用完成后才能访问类的成员。 理想情况下,我希望最终得到的是我可以在脚本中调用它:

courses.getCourse('xyz').complete = function () { // do something with the code } 

这只会在AJAX调用完成并且“类”中的数据结构准备好使用之后才会触发。 理想情况下,我不想为类中的每个函数创建.complete成员

这是我到目前为止所做的“课程”:

 var model_courses = (function() { var cls = function () { var _storage = {}; // Used for storing course related info _storage.courses = {}; // Used for accessing courses directly _storage.references = new Array(); // Stores all available course IDs var _ready = 0; $.ajax({ type: "GET", url: "data/courses.xml", dataType: "xml", success: function(xml) { $(xml).find("course").each(function() { _storage.courses[$(this).attr('id')] = { title : $(this).find('title').text(), description : $(this).find('description').text(), points : $(this).find('points').text() } _storage.references.push($(this).attr('id')) }) } }) console.log(_storage.courses) } cls.prototype = { getCourse: function (courseID) { console.log(cls._storage) }, getCourses: function () { return _storage.courses }, getReferences: function (), return _storage.references } } return cls })() 

目前,getCourse将在AJAX请求完成之前被触发,显然它将无法访问数据。

任何想法将不胜感激,我坚持这一个!

以下更改允许您只进行一次AJAX请求,您可以调用您的函数

 courses.getCourse('xyz', function(course){ // Use course here }); 

这是变化

 var model_courses = (function() { // This is what gets returned by the $.ajax call var xhr; var _storage = {}; // Used for storing course related info _storage.courses = {}; // Used for accessing courses directly _storage.references = []; // Stores all available course IDs var cls = function () { xhr = $.ajax({ type: "GET", url: "data/courses.xml", dataType: "xml", success: function(xml) { $(xml).find("course").each(function() { _storage.courses[$(this).attr('id')] = { title : $(this).find('title').text(), description : $(this).find('description').text(), points : $(this).find('points').text() } _storage.references.push($(this).attr('id')) }); } }); } cls.prototype = { // Made changes here, you'd have to make the same // changes to getCourses and getReferences getCourse: function (courseID, callback) { if (xhr.readyState == 4) { callback(_storage.courses[courseID]); } else { xhr.done(function(){ callback(_storage.courses[courseID]); }) } }, getCourses: function () { return _storage.courses }, getReferences: function (), return _storage.references } } return cls })() 

作为旁注,如果需要实例化其中两个model_courses对象,则模块模式将无法正常工作,因为存储对象都在自调用函数的闭包中共享。 您通常不会将模块模式与原型混合(从模块返回构造函数),除非您确实知道自己在做什么,也就是说,共享闭包变量作为类的静态属性。

如果我是你,我会这样做(因为你真的想要私有变量)

 function ModelCourses() { var storage = { courses: {}, references: [] }; var xhr = $.ajax({ type: "GET", url: "data/courses.xml", dataType: "xml", success: function(xml) { $(xml).find("course").each(function() { storage.courses[$(this).attr('id')] = { title : $(this).find('title').text(), description : $(this).find('description').text(), points : $(this).find('points').text() } storage.references.push($(this).attr('id')) }) } }); this.getCourse = function(courseId, callback) { function getCourse() { callback(storage.courses[courseID]) } if (xhr.readyState == 4) { getCourse(); } else { xhr.done(getCourse); } }; } 

jQuery已经使用延迟对象为你处理这个问题,除非我误解了你在寻找什么。

 var courses = { getCourse: function (id) { return $.ajax({url:"getCourse.php",data:{id:id}); } }; courses.getCourse("history").done(function(data){ console.log(data); }); 

我知道这不是你想要的,我希望它足以让你朝着正确的方向前进。 延迟对象很棒。

getStorage中添加一个检查以查看是否有任何数据要盗窃(首选),或者将“实际”方法设为私有,而不是在它具有可访问的项目时公开它。 (我会推荐第一个,否则你会得到关于调用一个对象上不存在的方法的例外)。

您可以定义一个函数getData来执行ajax请求,并将getCourse作为回调。 getData可能在本地存储Ajax调用的结果,并在执行ajax调用之前测试本地存储。

您还可以指定一个私有成员,以允许ajax调用仅运行一次。 您可能需要检查underscore.js以获得一些方便的工具

这是一个简短的示例代码:

 cls.prototype.getData = function(callback) { /*perform ajax call or retrieve data from cache*/ callback() } cls.prototype.getCourse = function(id) { this.getData(function() { /*do something with the data and the id you passed*/ } }