"Outsource" 将重复代码转换为带参数的函数 (js)
"Outsource" recurring code into a function with parameters (js)
所以我使用一个 js 文件来加载多个 html 和 js 文件,只要它们需要。我有大量模块的工作代码。在下面的示例中,您可以看到前两个模块。他们看起来都一模一样。现在我想 "outsource" 将重复代码放入一个带有参数的函数中,以便整体代码量最小化。因为我从来没有做过这样的事情,所以我需要一些帮助(我现在正在学习 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");
});
});
}
可能是这样的:
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");
});
});
}
这个问题回答起来相当复杂,因为要说明的事情很多。
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
回调被调用(函数作为第二个参数)。
- 如果
$.getScript
不行,我们给cache
加一个函数,无非是告诉你不行,之后,done
调用回调(第一个参数为错误)。
- 如果
name
确实存在于 cache
中,我们将在退出 module
函数后立即调用 done
回调
那么,这个怎么用呢?
现在归结为调用 module
函数
module('#placeone', 'PlaceOneModule', function(error, PlaceModule) {
if (error) throw new Error(error);
var instance = new PlaceModule(id, initial);
// ...
}
我为回调函数使用了通用的 function(error, value) {..}
签名,它始终将错误作为第一个参数(允许添加其他参数并使其成为可选参数)。
有一些caveats/assumptions值得一提:
- 如果之前对
module
的调用仍在加载 ,我没有提供故障保护来防止同一模块的多次加载(因此它与您的示例中的相同)
- 无论您用什么
target
调用 module
,它只会加载 'once'(好吧,请参阅上一行 ;-))
- 我假设加载的模块在全局 (
window
) 范围内以保持示例简单,请记住不要 'pollute the global scope'
这已经成为一个相当详尽的答案,我希望我充分解释了涉及的每个步骤。
所以我使用一个 js 文件来加载多个 html 和 js 文件,只要它们需要。我有大量模块的工作代码。在下面的示例中,您可以看到前两个模块。他们看起来都一模一样。现在我想 "outsource" 将重复代码放入一个带有参数的函数中,以便整体代码量最小化。因为我从来没有做过这样的事情,所以我需要一些帮助(我现在正在学习 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");
});
});
}
可能是这样的:
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");
});
});
}
这个问题回答起来相当复杂,因为要说明的事情很多。
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
回调被调用(函数作为第二个参数)。 - 如果
$.getScript
不行,我们给cache
加一个函数,无非是告诉你不行,之后,done
调用回调(第一个参数为错误)。
- 如果
- 如果
name
确实存在于cache
中,我们将在退出module
函数后立即调用done
回调
那么,这个怎么用呢?
现在归结为调用 module
函数
module('#placeone', 'PlaceOneModule', function(error, PlaceModule) {
if (error) throw new Error(error);
var instance = new PlaceModule(id, initial);
// ...
}
我为回调函数使用了通用的 function(error, value) {..}
签名,它始终将错误作为第一个参数(允许添加其他参数并使其成为可选参数)。
有一些caveats/assumptions值得一提:
- 如果之前对
module
的调用仍在加载 ,我没有提供故障保护来防止同一模块的多次加载(因此它与您的示例中的相同)
- 无论您用什么
target
调用module
,它只会加载 'once'(好吧,请参阅上一行 ;-)) - 我假设加载的模块在全局 (
window
) 范围内以保持示例简单,请记住不要 'pollute the global scope'
这已经成为一个相当详尽的答案,我希望我充分解释了涉及的每个步骤。