“外包”重复代码到带参数的函数(js)

时间:2016-02-08 08:42:07

标签: javascript minimize reducing

所以我使用一个js文件在需要时加载多个html和js文件。我有一个很多模块的工作代码。在下面的示例中,您可以看到前两个模块。所有这些都看起来完全一样。现在我想将重复代码“外包”到带参数的函数中,以便整个代码量最小化。因为在我需要一些帮助之前我从未做过这样的事情(我现在正在学习js)。我真的很感激一些帮助。

 //first module
 if (moduleID === "placeone") {
            var isLoaded = 0;
            if (isLoaded) {
                console.log("file already loaded");
                returnValue = new PlaceOneModule(id, moduleInitialData);
            }
            $("#placeone").load("html/modules/PlaceOneModule.html", function (response, status, xhr) {
                console.log("PlaceOneModule.html" + " " + status);
                $.getScript("js/modules/PlaceOneModule.js").done(function () {
                    console.log("PlaceOneModule.js geladen");
                    isLoaded = 1;
                    returnValue = new PlaceOneModule(id, moduleInitialData);
                }).fail(function () {
                    console.log("PlaceOneModule.js nicht geladen");
                });
            });
        }

    //second module
        if (moduleID === "placetwo") {
            var isLoaded = 0;
            if (isLoaded) {
                console.log("file already loaded");
                returnValue = new PlaceTwoModule(id, moduleInitialData);
            }
            $("#placetwo").load("html/modules/PlaceTwoModule.html", function (response, status, xhr) {
                console.log("PlaceTwoModule.html" + " " + status);
                $.getScript("js/modules/PlaceTwoModule.js").done(function () {
                    console.log("PlaceTwoModule.js geladen");
                    isLoaded = 1;
                    returnValue = new PlaceTwoModule(id, moduleInitialData);
                }).fail(function () {
                    console.log("PlaceTwoModule.js nicht geladen");
                });
            });
        }

2 个答案:

答案 0 :(得分:2)

回答这个问题相当复杂,因为有很多事情要考虑。

var cache = {};

function module(name, target, done) {
    if (!(name in cache)) {
        return $(target).load('html/modules/' + name + '.html', function(response, status, xhr) {
            console.log(name + '.html ' + status);

            $.getScript('js/modules/' + name + '.js')
                .done(function() {
                    console.log(name + '.js geladen');
                    cache[name] = window[name];

                    done(null, cache[name]);
                })
                .fail(function() {
                    var message = name + '.js nicht geladen';

                    cache[name] = function() {
                        console.error(message);
                    };

                    done(message);
                });
        });
    }

    setTimeout(function() {
        done(null, cache[name]);
    }, 0);
}

我会尝试解释我背后的思路:

  • var cache = {} - 您需要一些东西来跟踪每个单独的模块
  • function module(name, target, done) {
    • name将是您模块的基本名称,例如PlaceTwoModule,这已经在html和js文件以及js函数名称
    • 中一致使用
    • target将是应加载html文件的选择器
    • 由于您采取的操作之一需要异步操作,整个功能需要变为异步,我引入了一个回调(done)参数
  • if (!(name in cache)) - 如果模块尚未缓存,则需要一些提取,因此首先触发load
  • load完成后,会触发$.getScript
    • 如果$.getScript成功,则name将被假定为window,并且引用存储在cache变量中,之后,done调用1}}回调(函数作为第二个参数)。
    • 如果$.getScript没有成功,我们会向cache添加一个功能,这只会告诉您它不起作用,之后,{{1}调用callback(第一个参数有错误)。
  • 如果done中确实存在name,我们将在退出cache函数后立即调用done回调

那么,如何使用它呢? 它现在归结为调用module函数

module

我使用了回调函数的公共module('#placeone', 'PlaceOneModule', function(error, PlaceModule) { if (error) throw new Error(error); var instance = new PlaceModule(id, initial); // ... } 签名,它总是将错误作为第一个参数(允许添加其他参数并使其成为可选参数)。

值得一提的是一些警告/假设:

  • 如果先前对function(error, value) {..}的调用仍在加载
  • ,我没有提供用于防止同一模块的多次加载的故障保护(因此它与您的示例中的相同)
  • 无论您使用module调用target,它都只会加载一次' (好,见前一行;-))
  • 我假设加载的模块位于全局(module)范围内,以保持示例简单,请记住,不要'pollute the global scope'

这已成为一个相当精细的答案,我希望我已经充分解释了所涉及的每一步。

答案 1 :(得分:1)

可能是这样的事情:

 var modules = [];
 modules.push({
   js: 'PlaceOneModule',
   id: 'placeone'
 });

 modules.push({
   js: 'PlaceTwoModule',
   id: 'placetwo'
 });

 var module = modules.filter(function(m) {
   return m.id === moduleID;
 });

 if (module) {
   var isLoaded = 0;
   if (!!window[module.js]) {
      console.log("file already loaded");
      returnValue = window[module.js];
   }

   $("#" + module.id).load("html/modules/" + module.js + ".html", function(response, status, xhr) {
     $.getScript("js/modules/" + module.js + ".js").done(function() {
        returnValue = new window[module.js](id, moduleInitialData);
     }).fail(function() {
        console.log("PlaceOneModule.js nicht geladen");
     });
   });
 }