例如:
// run this:
alert('Loading...');
// dont run this again:
alert('Loading...');
我不想再重复一次。 我该如何方便地执行此操作(最好不使用布尔值)?
答案 0 :(得分:2)
标准方法是使用布尔标志。
但是,如果您对booleans
感到厌恶,则可以通过覆盖函数来做到这一点,从而确保从字面上不再可以再次调用它。
function loadButOnlyOnce() {
console.log('This will only happen once!');
loadButOnlyOnce = function() {};
}
loadButOnlyOnce();
loadButOnlyOnce();
您的IDE可能会发出“您在做什么,这将覆盖该功能!”的警告。但这是您的代码,您可以根据需要进行操作。
那么,现在您想要可以与其他功能一起使用的通用解决方案?您可以这样操作:
function allowOnlyOneCall(f) {
return function() {
f.apply(this, arguments);
f = function() {};
}
}
function myMethod(p1) {
console.log('myMethod is being invoked. p1 = ' + p1);
}
myMethod = allowOnlyOneCall(myMethod);
myMethod(5);
myMethod(5);
答案 1 :(得分:0)
这是您可以使用的一种简洁的实现,因此您可以避免对不想重复的每个任务使用布尔值:
var cache = [];
function do_once(task, fn) {
if(cache.indexOf(task) == -1) { // shorthand: !~cache.indexOf(task)
cache.push(task);
return fn();
}
}
用法:
var alertLoading = alert.bind(null, "Loading...");
do_once("alert_loading", alertLoading); // will run
// later on...
do_once("alert_loading", alertLoading); // will not run again
只要您给每个任务都不想重复一个不同的名称,此方法就起作用。无论作为do_once
的第二个参数提供的功能如何,只要已经使用相同的任务名称调用do_once
,它就不会运行。
答案 2 :(得分:0)
首先创建一个变量来存储函数是否已经运行(例如hasRun
)。然后只需将您的功能存储在if
条件中,该条件将检查此变量是否为false
。首次运行逻辑后,您需要更新此变量。
这可以在下面看到:
hasRun = false;
document.getElementsByTagName('button')[0].addEventListener('click', function() {
if (!hasRun) {
console.log('Loading...'); // Gets run once
hasRun = true; // Set the flag to true so the conditional doesn't get entered again
} else {
console.log('The function already ran!'); // Runs every subsequent time
}
})
<button>Click me</button>
答案 3 :(得分:0)
如果您想要一个工厂函数来记住以单个primitive value作为参数调用函数的结果,则应使用Map
:
const once = (() => fn => {
const cache = new Map()
return value => {
if (!cache.has(value)) {
cache.set(value, fn(value))
}
return cache.get(value)
}
})()
function verboseSquare (value) {
console.log('expensive calculation')
return value * value
}
const squareOnce = once(verboseSquare)
console.log(squareOnce(4))
console.log(squareOnce(4)) // skipped work
console.log(squareOnce(5))
console.log(squareOnce(5)) // skipped work