【问题标题】:What is the best method for loading in dependencies & instantiating object only once in Javascript?在Javascript中加载依赖项和实例化对象的最佳方法是什么?
【发布时间】:2016-11-26 07:12:32
【问题描述】:

我想在 Javascript 中探索久经考验、经过验证的设计模式,以确保只加载一次依赖项(如果它们已经加载),并且在 DOM 中也只实例化一次对象。

具体来说,我有以下几点:

// Block A in the DOM
<script>
//instantiate my golden object as follows
var some_unique_options = {
   "option1": "some-val",
   "option2": "some-val"
     }
   $.ajaxSetup({cache:true});
   $.getScript('my_golden_script.js', function(){
        golden_object.init(some_unique_options);
    });
</script>

// Block B in the DOM
<script>
//instantiate my golden object as follows
var another_unique_options ={
    "option1": "some-val",
    "option2": "some-val"
   }
   $.ajaxSetup({cache:true});
   $.getScript('my_golden_script.js', function(){
        golden_object.init(another_unique_options);
   });
</script>

目前,我的golden_object 实现了一个单例:http://robdodson.me/javascript-design-patterns-singleton/

这里的预期行为是,当上述 Bock A & B 在 DOM 中从上到下执行时,Block B 中的golden_object.init 将利用 Block A 操作期间定义的资源。业务需求是 Block A & B 将是相同的,并且 DOM 中可能有更多。经过几天的研究,我仍然无法提出一个坚实的结构。我的单例不断将自己重新创建为新的,并且只有当我在 devtools 控制台中调用 golden_object.init(); 时,它才会使用 DOM 中的现有对象。我怎样才能让它按照它应该的方式工作?我在这里/哪里犯了错误?

仅供参考,golden_object.js 确实通过 $.getScript() 携带 $.fn.someOtherObj 和几个依赖项以及单例的定义(我希望单例 obj 成为用户界面)

感谢您的见解和建议!

【问题讨论】:

    标签: javascript jquery dom promise singleton


    【解决方案1】:

    您可以在 jQuery.getScript 周围创建一个包装器,以确保脚本只加载一次,并且在第二个和更多实例的情况下,在第一个脚本加载后调用 callback

    jQuery.getScriptOnce = (function($) {
        var urls = {};
        return function(url, callback) {
            var obj = urls[url];
            if (!obj) {
                urls[url] = new Promise(function(resolve, reject) {
                    $.getScript(url, function(script, textStatus, jqXHR) {
                        resolve({script: script, textStatus: textStatus, jqXHR: jqXHR});
                        callback(script, textStatus, jqXHR);
                    });
                });
            } else {
                obj.then(function(val) {
                    callback(val.script, val.textStatus, val.jqXHR);
                });
            }
        };
    })(jQuery);
    

    这样做的好处是只需将所有出现的$.getScript 更改为$.getScriptOnce

    注意:我没有检查jQuery.getScript 是否返回一个 jQuery 承诺,如果返回,那么代码可以简单很多

    刚刚测试,似乎 getScript 确实返回了一个 jquery 承诺 - 所以你可以简单地做

    jQuery.getScriptOnce = (function($) {
        var urls = {};
        return function(url) {
            return urls[url] = urls[url] || $.getScript(url);
        };
    })(jQuery);
    

    但你会改变

    $.getScript('my_golden_script.js', function(){
        golden_object.init(some_unique_options);
    });
    

    $.getScriptOnce('my_golden_script.js').then(function(){
        golden_object.init(some_unique_options);
    });
    

    【讨论】:

      猜你喜欢
      • 2015-04-26
      • 1970-01-01
      • 2015-09-23
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 2011-10-22
      相关资源
      最近更新 更多