I presume it is possible to create a JavaScript function that disables it self after it is done running.
Is possible? How can this effect be achieved?
Wrap arbitrary runnable in following manner:
function once(subject) {
var first = true;
return function() {
if (first) {
first = false;
return subject();
} else {
return null;
}
};
}
var wrapper = once(function() {alert("No more!");});
wrapper(); // alerts
wrapper(); // noop
Runnable will only be executed on first invocation of wrapper.
You can convert a function of arbitrary arguments to an argumentless runnable.
If you want the functionality to be happen only once you can use the following function
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
// Usage
var canOnlyFireOnce = once(function() {
console.log('Fired!');
});
canOnlyFireOnce(); // "Fired!"
canOnlyFireOnce(); // nada
Courtesy: https://davidwalsh.name/essential-javascript-functions
something like this?
function a(){ alert(1); a = null;}
invoke a() once, second time it will say
Uncaught TypeError: a is not a function
if the function is anonymous, then make it IIFE
(function(){ alert(1);})();
var _flag = true; // Have a flag variable.
function oneTimer(){
// Check flag is set to true or not
if(!_flag) return;
_flag = false;
// Your function definition here.
}
As commented, if you want to execute a function only once, you should try IIFE. These functions are invoked immediately and cannot be called afterwards.
Following is a sample code.
(function test() {
console.log("test");
(function innerFunc() {
console.log("Inner Function");
})();
try {
innerFunc();
} catch (ex) {
console.log(ex)
}
})();
try {
test();
} catch (ex) {
console.log(ex)
}
Pretty easy, just assign an empty function to the function:
function once() {
alert('once');
once = function () { };
}
once();
once();
Related
How can you pass arguments to a function when implementing the Revealing module pattern in JavaScript. I have a module like this
var GlobalModule = (function() {
function consoleLog(textToOutput) {
console.log(textToOutput);
}
return {
consoleLog: consoleLog()
};
})();
Later on, when i run GlobalModule.consoleLog("Dummy text");, I get undefined as the output.
return {
consoleLog: consoleLog()
};
That part of your code is wrong.
You're exporting the Result of the consoleLog call due to the () at the end of the function, where you want to export the function itsself.
So just remove the function call:
return {
consoleLog: consoleLog
};
Do with function inside the return object
var GlobalModule = (function() {
return {
consoleLog: function(textToOutput)
{
console.log(textToOutput);
}
}
})();
GlobalModule.consoleLog("Dummy text");
Simply Do like this same output achieved . object => function call .No need a return object
var GlobalModule ={
consoleLog: function(textToOutput) {
console.log(textToOutput);
}
}
GlobalModule.consoleLog("Dummy text");
Change the line
consoleLog: consoleLog()
To
consoleLog: consoleLog
Or even(es6) to:
consoleLog
You can do like this
var GlobalModule = (function() {
function consoleLog(textToOutput) {
console.log(textToOutput);
}
return {
consoleLog: consoleLog // () is removed otherwise it will execute immediately
};
})();
GlobalModule.consoleLog('Hello')
DEMO
You you want to pass a global variable pass it in the parenthesis of the IIFE
var GlobalModule = (function(x) {
function consoleLog(textToOutput) {
console.log(textToOutput,x); // will log Hello temp
}
return {
consoleLog: consoleLog
};
})('temp');
I'm dealing with a stubborn API, and I need to stop a function executing on the first call, and then execute normally afterwards.
Currently I'm doing it like this:
var counter = 0;
function notFirstTime() {
counter++;
if (counter > 2) {
return;
}
}
Is there a better way of doing this?
You can use function that "returns function" for such cases:
function skipFirstCall(fun) {
var first_called = true;
return function() {
if (!first_called) {
fun.apply(this, arguments);
}
first_called = false;
}
}
var myFunc = skipFirstCall(function(){
console.log("I was executed!");
});
myFunc();
myFunc(); // I was executed!
myFunc(); // I was executed!
myFunc(); // I was executed!
You can pass any function to skipFirstCall function as argument to skip its first call:
var myAnotherFunc = skipFirstCall(function(){
console.log("myAnotherFunc was executed!");
});
myAnotherFunc();
myAnotherFunc(); // myAnotherFunc was executed!
myAnotherFunc(); // myAnotherFunc was executed!
Yes! there's a simple and elegant solution - you can redefine the function on the first call, like so:
var foo = function() {
foo = function() {
console.log("i'm after the 1st call");
}
}
The first time you call foo(), it rewrites the foo variable and sets it to a new function.
I trying to create a function, that takes another function as the argument, and creates a new version of the callback function that can only be called once. Subsequent calls will return the output if the initial call.
This is along the lines of recreating the Underscore .once method.
Here is what I have thus far. I have created a chargeCreditCard function. I want to create a new version of this function that can only be called once (chargeOnce). Explanation is appreciated. Thanks.
Edit. I want the once function to not rely on any code outside of the function to work (ie. an external counter variable).
var chargeCreditCard = function(num, price){
return num*price;
};
function once (func) {
var hasActionBeenCalled = false;
var call = function () {
if(!hasActionBeenCalled) {
hasActionBeenCalled = true;
func;
}
}
}
var chargeOnce = once(chargeCreditCard);
console.log(chargeOnce(2,3));
console.log(chargeOnce(4,5));
Your function once does not return anything, and your function call does not call anything. Make it
function once(func) {
var hasActionBeenCalled = false;
return function() {
if (!hasActionBeenCalled) {
hasActionBeenCalled = true;
return func.apply(this, arguments);
}
}
}
For garbage collection, I'd recommend to do
function once(func) {
var res;
return function() {
if (typeof func == "function") {
res = func.apply(this, arguments);
func = null; // unset func
}
return res;
}
}
How can I call the function only for once?
var myFunction = function () {
alert("calling function only for once");
}
myFunction();//alert "calling function only for once"
myFunction();//should not alert // if I call multiple times this should not be called
Try this:
var myFunction = function () {
alert("calling function only for once");
myFunction = function(){
return false;
}
}
myFunction();//alert "calling function only for once"
myFunction();//should not alert
Store some goobal variable a flag when run the function and check that variable at the start of the function.
set a flag, and call according to that flag:
var IsAlreadyCalled=false;
var myFunction = function () {
if(!IsAlreadyCalled){
alert("calling function only for once");
IsAlreadyCalled = true;
}
}
myFunction();//alert "calling function only for once"
myFunction();//should not alert
In your very odd scenario , the easiest way is to set a boolean:
var run = true,
myFunction = function(){
if(run){
alert('calling function only for once');
run = false;
} else {
return false;
}
};
myFunction(); // will run
myFunction(); // won't run
That way later on if you need to "reactivate" it you can just set the boolean back to true and call it again.
run = true;
myFunction(); // will run again
Other suggestions of using a flag are fine, but I would build it as a function decorator, that you can apply to any function. You avoid global variables this way, and your code becomes more readable and reusable:
// Takes a function and returns a function
// that executes only once
function once(f) {
var flag;
return function() {
if (!flag) {
flag = true;
return f.apply(this, arguments);
}
};
}
var fn = once(function() {
console.log('logged!');
});
fn(); // logged!
fn();
fn();
Demo: http://jsbin.com/povu/1/edit
function MyFunction () {
if (SomeCondition) {
MyInnerFunction(SomeParam);
return;
}
if (SomeOtherCondition) {
MyInnerFunction(SomeOtherParam);
return;
}
if (SomeThirdCondition) {
MyInnerFunction(AnotherParam);
return;
}
function MyInnerFunction(Param) {
// Do some work here
// HERE: I want return from MyFunction
}
}
As you can see, when MyInnerFunction returns, the next statement to execute is the return statement of MyFunction. Is there a way to eliminate all these return statements so that the return from MyFunction executes inside MyInnerFunction?
Thanks.
you could reformat the code so that your if conditions are only modifying the parameters.
Then you just call your method with the correct parameters at the end
function MyFunction () {
var params;
if (SomeCondition)
params = SomeParam;
else if (SomeOtherCondition)
params = SomeOtherParam;
else if (SomeThirdCondition)
params = AnotherParam;
MyInnerFunction(params);
}