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.
Related
I create a function as a variable to print 'Welcome' to console. I want to execute that variable as a function inside another new function. How can I do that?
This is my first function:
var first = function() {
console.log("Welcome");
}
You can just use it after it has been initialized:
var first = function() {
console.log("Welcome");
}
var second = function() {
first();
}
var firstFunction = function() {
//Your code that what you want to do
}
var second = function() {
firstFunction(); // calling first function
}
Is it possible to pass a callback function that does not exist yet? My goal is to have a common function that will wait for another callback function to exist, when it does exist, it should execute it. This is what I have so far, but I can't figure out how to pass the function in that doesn't exist as a function yet.
function RunTemplateFunction(callback, userInfo) {
if ($.isFunction(callback)) {
callback(userInfo);
} else {
var myInterval = setInterval(function () {
if ($.isFunction(callback)) {
clearInterval(myInterval);
callback(userInfo);
}
}, 200);
}
}
I run the function like this:
RunTemplateFunction(MyFunctionToRun, GetUserInfo());
I get MyFunctionToRun is undefined for obvious reasons, I also tried the workaround of passing the function as a string and then convert the string to a function using eval(). But that throws the same error. I also thought of using the new function(), but that actually creates a new function.
Any help is appreciated. thank you.
If you call RunTemplateFunction by undefined there is no way we can see, is callback is defined or not, as we don't have reference to anything.
If you can modify the declaration to accept object as below, we can achieve what we want
function RunTemplateFunction(options, userInfo) {
if ($.isFunction(options.callback)) {
console.log('called1',userInfo);
options.callback(userInfo);
} else {
var myInterval = setInterval(function () {
if ($.isFunction(options.callback)) {
console.log('Called dynamically!!');
clearInterval(myInterval);
options.callback(userInfo);
}
}, 200);
}
}
var options = {}
RunTemplateFunction(options,{user:122});
options.callback = function(){
console.log("I'm called!!");
}
This will print
Called dynamically!!
I'm called!!
EDIT:
We can also call callback function in following way without setInterval, it will look different but options.callback variable is replaced by template.callMe function and its instantaneous also.
function TemplateRunner(userInfo){
this.callMe = function(cb){
this.templateFunction(cb);
}
this.templateFunction = function(callback){
callback(userInfo);
}
}
var template = new TemplateRunner({user:100})
template.callMe(function(user){
console.log('call me1',user);
});
template.callMe(function(user){
console.log('call me2',user);
})
This will print
call me1 {user: 100}
call me2 {user: 100}
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();
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
Say I write this function...
var sayHi = function() {
return "hi";
}
alert(sayHi()); will return "hi".
Now if I write it this way...
var sayHi = function(callback) {
callback("hi");
}
How do I display "hi" with this function?
Based on an example here: http://nowjs.com/doc
You pass a function to sayHi, so I imagine this:
sayHi(alert);
you must have defined some callback function or pass a anonymous function:
var sayHi = function(callback) {
callback("hi");
}
sayHi(function(message){
alert(message);
});
Try this:
sayHi(function(msg){
alert(msg)
});
Your new sayHi function doesn't return a value, so you have to perform the alert in the callback function.
sayHi(function(value) {
alert(value);
});
sayHi(function(msg) {
alert(msg);
});
You have to invert your thinking process when using callbacks. Instead of writing the next operation first, you write the next operation last.
Here in example callback is a function. So you should pass function argument.
You may do this in 2 ways:
var some_fun = function(some_str) {
alert(some_str);
}
var sayHi = function(callback) {
callback("hi");
}
sayHi(some_fun)
or you can pass function when you call it:
var sayHi = function(callback) {
callback("hi");
}
sayHi(function(some_str){
alert(some_str);
});