制作功能等到AJAX调用完成与jQuery(Making functions wait until

2019-10-16 15:29发布

我试着开发一类在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
})()

目前AJAX请求完成之前getCourse将被解雇,显然不会有任何数据访问。

任何想法将不胜感激,即时通讯停留在这一个!

Answer 1:

下面的变化让你做出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);
        }
    };   
}


Answer 2:

jQuery的已经使用延迟对象,除非我误解你在找什么为您处理此。

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

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

我知道这是不是你在寻找什么,我希望这是足以推动你在正确的方向。 递延对象是真棒。



Answer 3:

getStorage要么添加一个检查,看看是否有任何数据窃取(首选),或使“实际”方法比公布它时,它有它可以访问的私人物品。 (我首先建议虽然否则你会得到有关调用不对象上存在的方法例外)。



Answer 4:

您可以定义一个函数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*/
    }
}


文章来源: Making functions wait until AJAX call is complete with jQuery