加载XML和JS以严格按顺序处理它

时间:2014-12-08 18:51:54

标签: javascript mootools

我目前正在构建自定义序列化功能。这会像这样变成一个数组

{user_ids: [1,2,3], types: ['foo', 'bar']}

成这样的字符串:

ui-1,2,3,,ty-foo,bar

我有一个XML文件告诉我" user_ids"映射到" ui"等我使用XML2JSON将XML文件转换为JavaScript可以使用的内容。

我想将缩写存储在本地存储中,以便下次需要它们时,我不需要再次获取XML文件或运行XML2JSON javascript。但是,我无法以正确的顺序执行所有操作。

缩写功能可以从页面的各个部分多次调用。它首先做的是检查本地存储是否已填满。如果不是,则必须加载XML,必须执行XML2JSON,结果必须放在本地存储中,然后才能继续。

Asset.javascript有一个onLoad(),Request有onComplete,但是他们并没有很好地等待彼此(似乎Asset.javascript是异步的,无论如何)。

我已尝试在每个函数中使用带callChain()的链(因此只有在他们真正完成了他们的工作后才会继续),但是我仍然坚持不得不返回一些东西 - 缩写函数的结果 - 我无法弄清楚。

var Shorten = {

dict: [],

compact: function(args){

    if(dict.length == 0){

        // Check local storage
        if(!localStorage.dict){

            new Request({
                url: 'shorten.xml',
                contentType: 'application/xml',
                method: 'get',
                onSuccess: (function(rdf){

                    Asset.javascript('xml2json.js', {
                        id: 'xml2json',
                        onLoad: (function(){

                            var x2js = new X2JS();
                            var jsonObj = x2js.xml_str2json(rdf);
                            var dict = [];

                            jsonObj.parameters.alias.each(function(alias){

                                dict[alias._long] = alias._short;
                            });

                            localStorage.dict = dict;
                        })
                    });
                })
            }).send();
        }
        else{

            this.dict = localStorage.dict;
        }
    }
    else{

        args.each(function(item){

            // Check dictionary and replace with abbreviated version.
        });
    }
}
};

1 个答案:

答案 0 :(得分:1)

你无法通过立即返回以任何有意义的方式解决这个问题,你有两种异步方法可以处理。

你可以按照(在5分钟内完成,但你得到回调的想法)重构:

var Shorten = {

    getSchema: function(rdf, done){
        Asset.javascript('xml2json.js', {
            id: 'xml2json',
            onLoad: function(){
                var x2js = new X2JS(),
                    jsonObj = x2js.xml_str2json(rdf),
                    dict = {};

                jsonObj.parameters.alias.each(function(alias){
                    dict[alias._long] = alias._short;
                });

                localStorage.setItem('dict', JSON.encode(dict));
                done(dict);
            }
        });
    },

    compact: function(args, done){
        var self = this,
            dict = localStorage.getItem('dict'),
            process = function(dict){
                args.each(function(item){
                // Check dictionary and replace with abbreviated version.
                });
                done();
            };     

        if (!dict){
            // Check local storage
            new Request({
                url: 'shorten.xml',
                contentType: 'application/xml',
                method: 'get',
                onComplete: this.getSchema.bind(this, process)
            }).send();
        } else {
            process(JSON.decode(dict));
        }
    }
};


Shorten.compact([{user_ids: [1,2,3], types: ['foo', 'bar']}], function(result){
    console.log(result);
});

我没有机会测试这个,但它应该让你开始走正确的道路。

一旦解决了,架构实际上存储在localStorage中,因此后续调用将返回良好且快速 - 您还可以重构以使架构成为返回模块的先决条件并使其像var shortString = Shorten.compact(args);一样同步 - 但是您需要预先嵌套模式调用 - 如果你知道它需要发生,你也可以。

您还可以预加载xml2json.js,这样您就不必依赖Asset.javascript JIT延迟加载,这意味着您可以通过一次异步调用来更快地处理事情以获取架构。您甚至可以使ajax请求同步(阻止UI)以进行链接和值立即返回,尽管回调/承诺是这种东西的正常模式

P.S。 dict是Object哈希,而不是Array