JS怎么做一次只能做一次

时间:2019-01-21 01:29:21

标签: javascript function

例如:

// run this:
alert('Loading...');

// dont run this again:
alert('Loading...');

我不想再重复一次。 我该如何方便地执行此操作(最好不使用布尔值)?

4 个答案:

答案 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