Function in javascript that can be called only onc

2019-01-02 22:42发布

I need to create a function which can be executed only once, in each time after the first it won't be executed. I know from C++ and Java about static variables that can do the work but I would like to know if there is a more elegant way to do this?

21条回答
欢心
2楼-- · 2019-01-02 22:50

If your using Node.js or writing JavaScript with browserify, consider the "once" npm module:

var once = require('once')

function load (file, cb) {
  cb = once(cb)
  loader.load('file')
  loader.once('load', cb)
  loader.once('error', cb)
}
查看更多
男人必须洒脱
3楼-- · 2019-01-02 22:51

You could simply have the function "remove itself"

​function Once(){
    console.log("run");

    Once = undefined;
}

Once();  // run
Once();  // Uncaught TypeError: undefined is not a function 

But this may not be the best answer if you don't want to be swallowing errors.

You could also do this:

function Once(){
    console.log("run");

    Once = function(){};
}

Once(); // run
Once(); // nothing happens

I need it to work like smart pointer, if there no elements from type A it can be executed, if there is one or more A elements the function can't be executed.

function Conditional(){
    if (!<no elements from type A>) return;

    // do stuff
}
查看更多
Ridiculous、
4楼-- · 2019-01-02 22:51

If you're using Ramda, you can use the function "once".

A quote from the documentation:

once Function (a… → b) → (a… → b) PARAMETERS Added in v0.1.0

Accepts a function fn and returns a function that guards invocation of fn such that fn can only ever be called once, no matter how many times the returned function is invoked. The first value calculated is returned in subsequent invocations.

var addOneOnce = R.once(x => x + 1);
addOneOnce(10); //=> 11
addOneOnce(addOneOnce(50)); //=> 11
查看更多
地球回转人心会变
5楼-- · 2019-01-02 22:52

If you want to be able to reuse the function in the future then this works well based on ed Hopp's code above (I realize that the original question didn't call for this extra feature!):

   var something = (function() {
   var executed = false;              
    return function(value) {
        // if an argument is not present then
        if(arguments.length == 0) {               
            if (!executed) {
            executed = true;
            //Do stuff here only once unless reset
            console.log("Hello World!");
            }
            else return;

        } else {
            // otherwise allow the function to fire again
            executed = value;
            return;
        }       
    }
})();

something();//Hello World!
something();
something();
console.log("Reset"); //Reset
something(false);
something();//Hello World!
something();
something();

The output look like:

Hello World!
Reset
Hello World!
查看更多
三岁会撩人
6楼-- · 2019-01-02 22:54

Reusable invalidate function which works with setInterval:

var myFunc = function (){
  if (invalidate(arguments)) return;
  console.log('called once and never again!'); // your stuff here
};

const invalidate = function(a) {
  var fired = a.callee.fired;
  a.callee.fired = true;
  return fired;
}

setInterval(myFunc, 1000);

Try it on JSBin: https://jsbin.com/vicipar/edit?js,console

Variation of answer from Bunyk

查看更多
女痞
7楼-- · 2019-01-02 22:55

Replace it with a reusable NOOP (no operation) function.

// this function does nothing
function noop() {};

function foo() {
    foo = noop; // swap the functions

    // do your thing
}

function bar() {
    bar = noop; // swap the functions

    // do your thing
}
查看更多
登录 后发表回答