Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使函数等待AJAX调用使用jQuery完成_Javascript_Jquery_Ajax_Oop - Fatal编程技术网

Javascript 使函数等待AJAX调用使用jQuery完成

Javascript 使函数等待AJAX调用使用jQuery完成,javascript,jquery,ajax,oop,Javascript,Jquery,Ajax,Oop,我正在尝试用JavaScript开发一个类,我可以使用它轻松访问AJAX请求收集的大量数据。唯一的问题是我只需要在AJAX调用完成后才能访问类的成员。理想情况下,我希望最终能够在脚本中调用: courses.getCourse('xyz').complete = function () { // do something with the code } 这只会在AJAX调用完成并且“类”中的数据结构准备就绪后触发。理想情况下,我不想为类中的每个函数都创建一个.complete成员 以下

我正在尝试用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请求完成之前启动,显然它将没有数据可访问


任何想法都会非常感激,我坚持这一点

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

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

courses.getCourse("history").done(function(data){
    console.log(data);
});

我知道这不正是你想要的,我希望这足以把你推向正确的方向。延迟对象非常棒。

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

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

courses.getCourse("history").done(function(data){
    console.log(data);
});

我知道这不正是你想要的,我希望这足以把你推向正确的方向。延迟对象非常棒。

getStorage
中,要么添加检查以查看是否有任何数据需要窃取(首选),要么将“实际”方法设置为私有,而不是在其具有可访问的项目时将其公开。(我建议使用第一种方法,否则调用对象上不存在的方法时会出现异常)。

getStorage
中,要么添加检查以查看是否有任何数据需要窃取(首选),要么将“实际”方法设置为私有,而不是在其具有可访问项时将其公开。(我建议使用第一种方法,否则调用对象上不存在的方法时会出现异常)。

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

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

下面是一个简短的示例代码:

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*/
    }
}

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

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

下面是一个简短的示例代码:

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*/
    }
}

下面的更改允许您只发出一次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\u课程
对象,那么模块模式将无法很好地工作,因为存储对象都在自调用函数的闭包中共享。您通常不会将模块模式与原型混合(从模块返回构造函数),除非您确实知道自己在做什么,即共享闭包变量作为类的静态属性工作

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


下面的更改允许您只发出一次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\u课程
对象,那么模块模式将无法很好地工作,因为存储对象都在自调用函数的闭包中共享。您通常不会将模块模式与原型混合(从模块返回构造函数),除非您确实知道自己在做什么,即共享闭包变量作为类的静态属性工作

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


调用
courses.getCourse('xyz',函数(course){…})
不可接受吗?这是处理异步操作的标准方法。调用
courses.getCourse('xyz',function(course){…})
是否不可接受?这是处理异步操作的标准方法。在保持脚本异步的同时,如何实现第一种方法?如果这样做有意义的话,我不希望页面上的其余脚本因上面的AJAX请求而延迟完成?我将如何在保持脚本异步的同时实现第一种方法?如果这有意义的话,我不希望页面上的其余脚本被搁置以完成上面的AJAX请求?这是朝着正确方向迈出的一步,是的,唯一的事情就像我说的,我希望能够将逻辑加载数据一次。理论上,我需要一些类似课程的东西。uu init.done(function(){cls.prototype={}但是,正如@Brad Christie在下面提到的,如果脚本在数据可用之前尝试访问成员,这将引发一个错误。除非使用某种回调(如“完成”回调),否则没有办法让试图访问数据的代码等待数据准备就绪(即使隐藏在另一个方法后面)要么总是需要回调,要么返回延迟对象,而不仅仅是输出数据。如果ajax请求已经完成,回调会立即执行。这是朝着正确方向迈出的一步。是的,唯一的事情就像我说的,我希望能够将逻辑加载数据一次。理论上,我需要类似c的东西我们的