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

Load XML and the JS to process it in a strictly sequential order

本文关键字:顺序处理 XML JS 加载      更新时间:2023-09-26

我目前正在构建一个自定义序列化函数。这会像这样转动数组

{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(( 的 Chain(因此它们只有在真正完成自己的工作后才会继续(,但是我仍然不得不返回一些东西 - 缩写函数的结果 - 我无法弄清楚。

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.
        });
    }
}
};
您无法

通过立即返回以任何有意义的方式解决此问题,您有 2 个异步方法需要处理。

您可以按照以下方式重构(在 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这样您就不会依赖 JIT 延迟加载Asset.javascript这意味着您只需一个异步调用即可更快地处理事情来获取架构。 您甚至可以使 ajax 请求同步(阻塞 UI(以用于链接和值立即返回,尽管回调/承诺是此类内容的正常模式

附言字典是一个Object哈希,而不是一个Array