If we have two function in javascript, one slow and one fast. For example:
function slow() {
setTimeout(function() {console.log("slow finished")}, 10000);
}
function fast() {
console.log("fast");
}
And these functions don't have inside of them new structures like promisses (if we do not implement after).
How can we force these functions run in order? For example:
function run() {
slow();
fast();
}
run();
How can we force fast wait slow finishes?
I'm looking a solution that could work inside mobile application browsers, becase of a Apache Cordova project of mine.
Is there a way to do this?
An idea of mine is inject a callback function between the functions.
And this callback is called at the end of the slow function, calling the fast function.
An important thing is I can't (or would not) rewrite the code of the slow and fast functions,
because they will reside inside external libraries.
I'm looking for a solution to countorn this problem as an external observer and manager.
How can we do this?
Edit
He I was a trying to solve the problem merging the answers. No success yet.
I had changed slow but this is not really allowed. I have changed it to se what is happening with a. I couldn't get something interesting because a becomes undefined immediately and not after slow finishes...
var a = "adsfadsfadsf";
function slow() {
setTimeout(function() {console.log("slow done"); console.log("a2", window.a);}, 3000);
}
function fast() {
console.log("a3", window.a);
console.log("fast done");
}
var newSlow = function() {
return new Promise(function(resolve, reject){
window.a = slow();
console.log("a", a);
resolve("Sucess");
});
};
newSlow().then(function(resolve){fast();}, function(reject){console.log("error");});
I have tried with resolve(slow()); no sucess too.
That's a very interesting question. Well I can think of a way where if it is changing some global variable "g" to some value say "true". In that case if you can run them sequentially as,
<script>
var g = false;
var i;
function slow() {
setTimeout(function() {console.log("slow finished");g=true;}, 10000);
}
function fast() {
console.log("fast");
}
function run() {
slow();
i = setInterval(function(){check();},1000);
}
function check(){
if(g){
fast();
clearInterval(i);
}
}
run();
</script>
As in this demo
UPDATE: Something just struck me and I guess we might be able to add a callback function to slow() even if we can't access it directly.
If a function is called without parenthesis then the entire function as a content is returned as a string so we can edit that string by adding fast() to it registering that string as a function using eval().
function run() {
var myFun = slow+"";
myFun = myFun.substring(0,myFun.length-1);
alert(myFun);
myFun += "fast();}";
//to register the string "myFun" as a function
eval(myFun);
slow();
}
So basically our slow() function becomes,
function slow(){
//function code
//the appended function
fast();
}
NOTE: This will not worked in the example given above where GarouDan has deliberately added setTimeout limit to recreate a scenario where the slow() function takes longer time than the fast() function. However, in a real-world scenario I'm sure this approach would definetly work.
You could use the Promise pattern.
Promises are tailor made for situations where various parts of code may run slow or fast or complete in unknowable amounts of time (or not complete at all), while still giving you execution control.
My personal favorite library that implements the Promise pattern is RSVP.
Here is some pseudocode to give you the idea. Run an operation that may take a long time, then run one only when the first has either completed, or handle it's failure.
function doFoo() {
var promise = new RSVP.Promise(function(resolve, reject) {
// do some long-running operation, like retrieve
// data from a slow site...
if (data.Status && data.Status === 200) {
resolve(data);
} else {
reject(data.Error)
}
});
return promise;
}
function doBar() {
var promise = new RSVP.Promise(function(resolve, reject) {
// do some fast operation, like count to 10
for (i = 0; i < 10; i++) {
console.log(i);
}
resolve("");
});
return promise;
}
Now you can call:
function inOrder() {
doFoo().then(function(success) {
doBar();
}).catch (function(failure) {
console.log("oops! " + failure);
}
});
}
This runs doFoo, and ONLY runs doBar after doFoo has completed successfully. Note that you could also run doBar even if doFoo has failed.
Related
I have a click event that is triggered from another place automatically for the first time. My problem is that it runs too soon, since the required variables are still being defined by Flash and web services. So right now I have:
(function ($) {
$(window).load(function(){
setTimeout(function(){
$('a.play').trigger("click");
}, 5000);
});
})(jQuery);
The problem is that 5 seconds for a person with a slow internet connection could be too fast and vice versa, for a person with a fast internet connection, it's too slow.
So how should I do the delay or timeout until someVariable is defined?
The following will keep looking for someVariable until it is found. It checks every 0.25 seconds.
function waitForElement(){
if(typeof someVariable !== "undefined"){
//variable exists, do what you want
}
else{
setTimeout(waitForElement, 250);
}
}
async, await implementation, improvement over #Toprak's answer
(async() => {
console.log("waiting for variable");
while(!window.hasOwnProperty("myVar")) // define the condition as you like
await new Promise(resolve => setTimeout(resolve, 1000));
console.log("variable is defined");
})();
console.log("above code doesn't block main function stack");
After revisiting the OP's question. There is actually a better way to implement what was intended: "variable set callback". Although the below code only works if the desired variable is encapsulated by an object (or window) instead of declared by let or var (I left the first answer because I was just doing improvement over existing answers without actually reading the original question):
let obj = encapsulatedObject || window;
Object.defineProperty(obj, "myVar", {
configurable: true,
set(v){
Object.defineProperty(obj, "myVar", {
configurable: true, enumerable: true, writable: true, value: v });
console.log("window.myVar is defined");
}
});
see Object.defineProperty
or use es6 proxy (which is probably overkill)
If you are looking for more:
/**
* combining the two as suggested by #Emmanuel Mahuni,
* and showing an alternative to handle defineProperty setter and getter
*/
let obj = {} || window;
(async() => {
let _foo = await new Promise(res => {
Object.defineProperty(obj, "foo", { set: res });
});
console.log("obj.foo is defined with value:", _foo);
})();
/*
IMPORTANT: note that obj.foo is still undefined
the reason is out of scope of this question/answer
take a research of Object.defineProperty to see more
*/
// TEST CODE
console.log("test start");
setTimeout(async () => {
console.log("about to assign obj.foo");
obj.foo = "Hello World!";
// try uncomment the following line and compare the output
// await new Promise(res => setTimeout(res));
console.log("finished assigning obj.foo");
console.log("value of obj.foo:", obj.foo); // undefined
// console: obj.foo is defined with value: Hello World!
}, 2000);
I would prefer this code:
function checkVariable() {
if (variableLoaded == true) {
// Here is your next action
}
}
setTimeout(checkVariable, 1000);
I prefer something simple like this:
function waitFor(variable, callback) {
var interval = setInterval(function() {
if (window[variable]) {
clearInterval(interval);
callback();
}
}, 200);
}
And then to use it with your example variable of someVariable:
waitFor('someVariable', function() {
// do something here now that someVariable is defined
});
Note that there are various tweaks you can do. In the above setInterval call, I've passed 200 as how often the interval function should run. There is also an inherent delay of that amount of time (~200ms) before the variable is checked for -- in some cases, it's nice to check for it right away so there is no delay.
With Ecma Script 2017 You can use async-await and while together to do that
And while will not crash or lock the program even variable never be true
//First define some delay function which is called from async function
function __delay__(timer) {
return new Promise(resolve => {
timer = timer || 2000;
setTimeout(function () {
resolve();
}, timer);
});
};
//Then Declare Some Variable Global or In Scope
//Depends on you
let Variable = false;
//And define what ever you want with async fuction
async function some() {
while (!Variable)
await __delay__(1000);
//...code here because when Variable = true this function will
};
////////////////////////////////////////////////////////////
//In Your Case
//1.Define Global Variable For Check Statement
//2.Convert function to async like below
var isContinue = false;
setTimeout(async function () {
//STOPT THE FUNCTION UNTIL CONDITION IS CORRECT
while (!isContinue)
await __delay__(1000);
//WHEN CONDITION IS CORRECT THEN TRIGGER WILL CLICKED
$('a.play').trigger("click");
}, 1);
/////////////////////////////////////////////////////////////
Also you don't have to use setTimeout in this case just make ready function asynchronous...
You can use this:
var refreshIntervalId = null;
refreshIntervalId = setInterval(checkIfVariableIsSet, 1000);
var checkIfVariableIsSet = function()
{
if(typeof someVariable !== 'undefined'){
$('a.play').trigger("click");
clearInterval(refreshIntervalId);
}
};
Here's an example where all the logic for waiting until the variable is set gets deferred to a function which then invokes a callback that does everything else the program needs to do - if you need to load variables before doing anything else, this feels like a neat-ish way to do it, so you're separating the variable loading from everything else, while still ensuring 'everything else' is essentially a callback.
var loadUser = function(everythingElse){
var interval = setInterval(function(){
if(typeof CurrentUser.name !== 'undefined'){
$scope.username = CurrentUser.name;
clearInterval(interval);
everythingElse();
}
},1);
};
loadUser(function(){
//everything else
});
Instead of using the windows load event use the ready event on the document.
$(document).ready(function(){[...]});
This should fire when everything in the DOM is ready to go, including media content fully loaded.
Shorter way:
var queue = function (args){
typeof variableToCheck !== "undefined"? doSomething(args) : setTimeout(function () {queue(args)}, 2000);
};
You can also pass arguments
I have upvoted #dnuttle's answer, but ended up using the following strategy:
// On doc ready for modern browsers
document.addEventListener('DOMContentLoaded', (e) => {
// Scope all logic related to what you want to achieve by using a function
const waitForMyFunction = () => {
// Use a timeout id to identify your process and purge it when it's no longer needed
let timeoutID;
// Check if your function is defined, in this case by checking its type
if (typeof myFunction === 'function') {
// We no longer need to wait, purge the timeout id
window.clearTimeout(timeoutID);
// 'myFunction' is defined, invoke it with parameters, if any
myFunction('param1', 'param2');
} else {
// 'myFunction' is undefined, try again in 0.25 secs
timeoutID = window.setTimeout(waitForMyFunction, 250);
}
};
// Initialize
waitForMyFunction();
});
It is tested and working! ;)
Gist: https://gist.github.com/dreamyguy/f319f0b2bffb1f812cf8b7cae4abb47c
Object.defineProperty(window, 'propertyName', {
set: value => {
this._value = value;
// someAction();
},
get: () => this._value
});
or even if you just want this property to be passed as an argument to a function and don't need it to be defined on a global object:
Object.defineProperty(window, 'propertyName', { set: value => someAction(value) })
However, since in your example you seem to want to perform an action upon creation of a node, I would suggest you take a look at MutationObservers.
I have an adaptation of the answer by #dnuttle that I would suggest using.
The advantage of using a try-catch block is that if any part of the code you are trying to execute fails, the whole block fails. I find this useful because it gives you a kind of transaction; everything or nothing gets done.
You should never write code that could end up in an endless loop due to external factors. This is exactly what would happen if you were waiting for a response from an ajax request and the server doesn't respond. I think it's good practice to have a timeout for any questionable loops.
let time = 0; // Used to keep track of how long the loop runs
function waitForElement() {
try {
// I'm testing for an element, but this condition can be
// any reasonable condition
if (document.getElementById('test') === null) {
throw 'error';
}
// This is where you can do something with your variable
// document.getElementById('test').addEventListener....
// or call a function that uses your value
} catch (error) {
// Loop stops executing if not successful within about 5 seconds
if (time > 5000) {
// I return false on failure so I can easily check for failure
return false;
} else {
// Increment the time and call the function again
time += 250;
setTimeout(waitForElement, 250);
}
}
}
// Call the function after the definition, ensures that time is set
waitForElement();
You could have Flash call the function when it's done. I'm not sure what you mean by web services. I assume you have JavaScript code calling web services via Ajax, in which case you would know when they terminate. In the worst case, you could do a looping setTimeout that would check every 100 ms or so.
And the check for whether or not a variable is defined can be just if (myVariable) or safer: if(typeof myVariable == "undefined")
Very late to the party but I want to supply a more modern solution to any future developers looking at this question. It's based off of Toprak's answer but simplified to make it clearer as to what is happening.
<div>Result: <span id="result"></span></div>
<script>
var output = null;
// Define an asynchronous function which will not block where it is called.
async function test(){
// Create a promise with the await operator which instructs the async function to wait for the promise to complete.
await new Promise(function(resolve, reject){
// Execute the code that needs to be completed.
// In this case it is a timeout that takes 2 seconds before returning a result.
setTimeout(function(){
// Just call resolve() with the result wherever the code completes.
resolve("success output");
}, 2000);
// Just for reference, an 'error' has been included.
// It has a chance to occur before resolve() is called in this case, but normally it would only be used when your code fails.
setTimeout(function(){
// Use reject() if your code isn't successful.
reject("error output");
}, Math.random() * 4000);
})
.then(function(result){
// The result variable comes from the first argument of resolve().
output = result;
})
.catch(function(error){
// The error variable comes from the first argument of reject().
// Catch will also catch any unexpected errors that occur during execution.
// In this case, the output variable will be set to either of those results.
if (error) output = error;
});
// Set the content of the result span to output after the promise returns.
document.querySelector("#result").innerHTML = output;
}
// Execute the test async function.
test();
// Executes immediately after test is called.
document.querySelector("#result").innerHTML = "nothing yet";
</script>
Here's the code without comments for easy visual understanding.
var output = null;
async function test(){
await new Promise(function(resolve, reject){
setTimeout(function(){
resolve("success output");
}, 2000);
setTimeout(function(){
reject("error output");
}, Math.random() * 4000);
})
.then(function(result){
output = result;
})
.catch(function(error){
if (error) output = error;
});
document.querySelector("#result").innerHTML = output;
}
test();
document.querySelector("#result").innerHTML = "nothing yet";
On a final note, according to MDN, Promises are supported on all modern browsers with Internet Explorer being the only exception. This compatibility information is also supported by caniuse. However with Bootstrap 5 dropping support for Internet Explorer, and the new Edge based on webkit, it is unlikely to be an issue for most developers.
while (typeof myVar == void(0)) {
if ( typeof myVar != void(0)) {
console.log(myVar);
}
}
This makes use of the typeof operator which only returns undefined if variable is not declared yet. Should be applicable in every type of javascript.
I have an Angular.js service which delivers its results asynchronously, after looking around for a while the main pattern for doing this seems to be using $q promises like this
angular.module('fooApp').factory('foo', function ($q) {
var result;
function build() {
var d = $q.defer();
longAsyncInit(function(data) {
result = data;
d.resolve(result);
});
return d.promise;
};
return {
get: function () {
if (result) {
return $q.when(result);
} else {
return build();
}
}
}
});
The problem is that I have a number of services which have this service as a dependency and get is called multiple times before the first longAsyncInit ends (which means that longAsyncInit gets called multiple times, each time creating a new promise). In my case this is unacceptable, I really need longAsyncInit to be called once, no more. I'm currently addressing this issue like this
angular.module('fooApp').factory('foo', function ($q) {
var result
var d;
function build() {
d = $q.defer();
longAsyncInit(function(data) {
result = data;
d.resolve(result);
});
return d.promise;
};
return {
get: function () {
if (result) {
return $q.when(result);
} else if (d) {
return d.promise;
} else {
return build();
}
}
}
});
This means if longAsyncInit is already ongoing when a get() call is made, it returns the current promise, instead of creating a new one and calling longAsyncInit again. This seems to work but feels inelegant and fragile, is there a better way of doing this?
You are looking for debounce method to solve problem.
From Underscore library documentation what _.debounce() do
Creates and returns a new debounced version of the passed function
which will postpone its execution until after wait milliseconds have
elapsed since the last time it was invoked. Useful for implementing
behavior that should only happen after the input has stopped arriving.
For example: rendering a preview of a Markdown comment, recalculating
a layout after the window has stopped being resized, and so on.
Some more explanations
Can someone explain the "debounce" function in Javascript
Some content to read:
http://davidwalsh.name/javascript-debounce-function
I am trying to check for the presence of a modal. If the modal is not present then it will place the value of the timer into browser.sleep(). This will give time for the modal to appear. I am having an issue with a for loop in a page object. When I run the code below I do not receive the alert and console.log messages under the if when I force a failure by getting changing the object. Also, I do not receive the Timer expired message.
from page_object file (relevant code)
editVinModal: { get: function () {
return browser.element({id: 'editableVINPart'});
}},
doEditVIN: { value: function () {
modalFailedToAppear = true;
console.log('In doEditVIN');
for(modal_timer = 0 ; modal_timer <= 30; modal_timer++) {
if (!(this.editVinModal)) {
alert('In If');
console.log('Modal failed to appear');
console.log('Under if - modalFailedToAppear: ', modalFailedToAppear);
browser.sleep(modal_timer);
console.log('under if - modal_timer: ',modal_timer);
}
else {
console.log('In else if else loop');
// console.log(browser.isElementPresent(this.editVinModal));
console.log('modalFailedToAppear: ',modalFailedToAppear);
modalFailedToAppear = false;
console.log('modalFailedToAppear: ',modalFailedToAppear);
console.log('modal_timer: ',modal_timer);
break;
}
}
if (modalFailedToAppear){
console.log("Modal is not present within the given time period. Timer has expired.");
}
this.editVinLink.click();
}},
Thanks in advance for
Looks like you're new around here. Welcome!
browser.sleep(), generally speaking, does not belong in your Protractor tests (except for debugging purposes). That's the bad news. The good news is that Protractor actually provides a function that does exactly (I think) what you're trying to do. It's called browser.wait() and it works like this:
browser.wait( function() {
return element(by.id('editableVINpart')).isPresent().then( function(present) {
return present;
});
}, 5000)
.then(function() {
element(by.id('editableVINpart')).click();
}, function() {
console.log('Element not found. :( ');
});
browser.wait() takes two arguments: first, an anonymous function, which it will execute repeatedly until it returns true; second, an amount of time to wait in milliseconds (by the way, browser.sleep() also takes a millisecond wait time, so your for loop is only waiting 465 milliseconds if it iterates all the way through, or about a half second--not very long).
Then, since browser.wait() returns a promise, just like all Protractor functions, we can attach a .then() statement to the end of it, which will execute the first passed-in function if the promise is successful, or the second passed-in function if it is not.
If you often have to wait for an element to be present (and for some reason it isn't synchronized with the Angular page load), it may be useful to you to have a reusable form of the function, like this:
var waitThenClick = function(el) {
browser.wait( function() {
return el.isPresent().then( function(present) {
return present;
});
}, 5000)
.then(function() {
el.click();
}, function() {
console.log('Element with locator: ' + el.locator + ' was not found. :( ');
});
};
Then you could just call it like this, for whatever element you need:
waitThenClick(element(by.id('editableVINpart')));
Good luck! Make sure to get good and clever with asynchronous stuff (especially promises) with problems like this. Protractor promises trip up the best of us.
Sorry if this question has already been asked here before, I could not find a suitable answer.
I am wanting to create a JavaScript sleep/delay/wait function that I can call anywhere in the script, like jQuery's .delay()
I am not able to use setTimeout, as I have a script that is generated by php, and so am not able to put it into two different functions, with the timeout in the middle. I need to create a function that allows me to do
alert("time started");
sleep(4000);
alert("time up");
I really do not want to use jQuery.
Here's a solution using the new async/await syntax.
async function testWait() {
alert('going to wait for 5 second');
await wait(5000);
alert('finally wait is over');
}
function wait(time) {
return new Promise(resolve => {
setTimeout(resolve, time);
});
}
Note: You can call function wait only in async functions
You cannot just put in a function to pause Javascript unfortunately.
You have to use setTimeout()
Example:
function startTimer () {
timer.start();
setTimeout(stopTimer,5000);
}
function stopTimer () {
timer.stop();
}
EDIT:
For your user generated countdown, it is just as simple.
HTML:
<input type="number" id="delay" min="1" max="5">
JS:
var delayInSeconds = parseInt(delay.value);
var delayInMilliseconds = delayInSeconds*1000;
function startTimer () {
timer.start();
setTimeout(stopTimer,delayInMilliseconds);
}
function stopTimer () {
timer.stop;
}
Now you simply need to add a trigger for startTimer(), such as onchange.
You will have to use a setTimeout so I see your issue as
I have a script that is generated by PHP, and so am not able to put it into two different functions
What prevents you from generating two functions in your script?
function fizz() {
var a;
a = 'buzz';
// sleep x desired
a = 'complete';
}
Could be rewritten as
function foo() {
var a; // variable raised so shared across functions below
function bar() { // consider this to be start of fizz
a = 'buzz';
setTimeout(baz, x); // start wait
} // code split here for timeout break
function baz() { // after wait
a = 'complete';
} // end of fizz
bar(); // start it
}
You'll notice that a inside baz starts as buzz when it is invoked and at the end of invocation, a inside foo will be "complete".
Basically, wrap everything in a function, move all variables up into that wrapping function such that the contained functions inherit them. Then, every time you encounter wait NUMBER seconds you echo a setTimeout, end the function and start a new function to pick up where you left off.
The behavior exact to the one specified by you is impossible in JS as implemented in current browsers. Sorry.
Well, you could in theory make a function with a loop where loop's end condition would be based on time, but this would hog your CPU, make browser unresponsive and would be extremely poor design. I refuse to even write an example for this ;)
Update: My answer got -1'd (unfairly), but I guess I could mention that in ES6 (which is not implemented in browsers yet, nor is it enabled in Node.js by default), it will be possible to write a asynchronous code in a synchronous fashion. You would need promises and generators for that.
You can use it today, for instance in Node.js with harmony flags, using Q.spawn(), see this blog post for example (last example there).
You can use this -
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
You could use the following code, it does a recursive call into the function in order to properly wait for the desired time.
function exportar(page,miliseconds,totalpages)
{
if (page <= totalpages)
{
nextpage = page + 1;
console.log('fnExcelReport('+ page +'); nextpage = '+ nextpage + '; miliseconds = '+ miliseconds + '; totalpages = '+ totalpages );
fnExcelReport(page);
setTimeout(function(){
exportar(nextpage,miliseconds,totalpages);
},miliseconds);
};
}
I have a javascript function that is being built to animate the collapse of a div, and then proceed with other jobs. The code is as follows:
function newsFeed() {
var self = this;
this.collapse = function(listingID,orig_height,curr_height,opacity) {
var listing = document.getElementById(listingID);
var reduceBy = 5;
if(curr_height > reduceBy) {
curr_height = curr_height-reduceBy;
listing.style.overflow = "hidden";
listing.style.height = (curr_height-40) + "px";
if(opacity > 0) {
opacity = opacity - 10;
var opaque = (opacity / 100);
listing.style.opacity=opaque;
listing.style.MozOpacity=opaque;
listing.style.filter='alpha(opacity='+opacity+')';
}
setTimeout(function() { self.collapse(listingID,orig_height,curr_height,opacity); },1);
}else{
return true;
}
}
this.remove = function(listingID) {
var listing = document.getElementById(listingID);
var currHeight = listing.offsetHeight;
if (this.collapse(listingID,currHeight,currHeight,100)) {
// DO SOME OTHER STUFF
}
}
}
var newsFeed = new newsFeed();
newsFeed.remove('closeMe');
I cannot get the this.remove function to wait while this.collapse finishes and returns true. Is this impossible? What is the best way to go on?
Important: I would like to be able to use this.collapse with other functions yet to be built in the same fashion as I do here.
I cannot get the this.remove function to wait while this.collapse finishes
That is correct, it is impossible to do so. In JavaScript there is a single flow of execution. When the browser calls your code you can do some processing, but for anything further to occur (timeouts or event calls) you must return control to the browser.
‘Asynchronous’ processes like collapse() are done by setting timeouts, so control must be returned to the browser many times; when remove() calls collapse() the first time it returns immediately after the first timeout is set; that timeout cannot be fired until remove() itself returns, so your 'if' code will only ever execute if the very first call to collapse() was the last frame of animation (ie. the element was 5px or smaller already). Otherwise collapse()'s ‘return true’ will just be returning true to the browser's timeout-caller, which doesn't care at all what value you return to it.
Some languages give you tools such as threads or coroutines that can allow an asynchronous routine to be run from a synchronous routine; JavaScript does not. Instead, remove() must supply collapse() with a callback function it can call itself on the last frame.
There is no way you can pause the execution in Javascript till something else happens. All you can do is attach a callback function to collapse to call after it is done executing the final step.
As a sidenote, jQuery provides functions like fade(), animate() etc and supports queuing. If you don't want to use jQuery, you can still look at the code to see how it's implemented.
See the examples in this page.
setTimeout is not a "sleep". The function will end right there and return "undefined".
To manage that, I think you should do something like:
var newsFeed = new newsFeed();
newsFeed.onaftercollapse = function () {
newsFeed.remove('closeMe'); // "newsFeed" or "self"? must test
};
And then instead of return true;, the collapse() will end with:
if (self.onaftercollapse) self.onaftercollapse();
This example demonstrates how to check if a function is complete.
function foo() {
foo.complete = false;
// your code here
foo.complete = true;
}
foo.complete = false;
if (foo.complete) { // foo execution complete
// your code here
}
This code demonstrates how to check if a function has been run once.
function foo() {
// your code here
foo.ranOnce || (foo.ranOnce = true);
}
foo.ranOnce = false;
if (foo.ranOnce) { // foo execution complete at least once
// your code here
}