I know how to execute a function once, this is not the question
First, this is my code
var executed1 = false;
var executed2 = false;
var executed3 = false;
function myFunction()
{
if(-------------------)
{
//Verification - If the others conditions have ever been called
if (executed2)
{
executed2 = false;
}
else if(executed3)
{
executed3 = false;
}
//Verification - If the condition have ever been called during this condition = true;
if (!execution1)
{
execution1 = true;
//My code here ...
}
}
else if (-------------------)
{
if (executed1)
{
executed1 = false;
}
else if(executed3)
{
executed3 = false;
}
if (!execution2)
{
execution2 = true;
//My code here ...
}
}
else if (-------------------)
{
//Same thing with execution3
}
}
setInterval("myFunction()", 10000);
I'll take the first condition, for example
(1) If the condition is true, I want to execute my code but only the first time : as you can see, my function is executed every 10s. As long as the first condition is true, nothing should append more.
If the first condition becomes false and the second condition true, it’s the same process.
But now, If the first condition ever been true and false, I would like that if the condition becomes true again, it will be the same thing that (1)
Is there any way to read a cleaner code to do that ?
Because, now there are only 3 conditions, but there may be 100.
use clearInterval to stop execution your function and one if to check conditions
var fid = setInterval(myFunction, 1000);
var cond = [false,false,false];
function myFunction()
{
console.log(cond.join());
// check conditions in some way here (e.g. every is true)
if(cond.every(x=>x)) {
clearInterval(fid);
console.log('Execute your code and stop');
}
// change conditions (example)
cond[2]=cond[1];
cond[1]=cond[0];
cond[0]=true;
}
Related
How do I break out of a jQuery each loop?
I have tried:
return false;
in the loop but this did not work. Any ideas?
Update 9/5/2020
I put the return false; in the wrong place. When I put it inside the loop everything worked.
To break a $.each or $(selector).each loop, you have to return false in the loop callback.
Returning true skips to the next iteration, equivalent to a continue in a normal loop.
$.each(array, function(key, value) {
if(value === "foo") {
return false; // breaks
}
});
// or
$(selector).each(function() {
if (condition) {
return false;
}
});
According to the documentation return false; should do the job.
We can break the $.each() loop [..] by making the callback function
return false.
Return false in the callback:
function callback(indexInArray, valueOfElement) {
var booleanKeepGoing;
this; // == valueOfElement (casted to Object)
return booleanKeepGoing; // optional, unless false
// and want to stop looping
}
BTW, continue works like this:
Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
I came across the situation where I met a condition that broke the loop, however the code after the .each() function still executed. I then set a flag to "true" with an immediate check for the flag after the .each() function to ensure the code that followed was not executed.
$('.groupName').each(function() {
if($(this).text() == groupname){
alert('This group already exists');
breakOut = true;
return false;
}
});
if(breakOut) {
breakOut = false;
return false;
}
I created a Fiddle for the answer to this question because the accepted answer is incorrect plus this is the first StackOverflow thread returned from Google regarding this question.
To break out of a $.each you must use return false;
Here is a Fiddle proving it:
http://jsfiddle.net/9XqRy/
I know its quite an old question but I didn't see any answer, which clarify that why and when its possible to break with return.
I would like to explain it with 2 simple examples:
1. Example:
In this case, we have a simple iteration and we want to break with return true, if we can find the three.
function canFindThree() {
for(var i = 0; i < 5; i++) {
if(i === 3) {
return true;
}
}
}
if we call this function, it will simply return the true.
2. Example
In this case, we want to iterate with jquery's each function, which takes anonymous function as parameter.
function canFindThree() {
var result = false;
$.each([1, 2, 3, 4, 5], function(key, value) {
if(value === 3) {
result = true;
return false; //This will only exit the anonymous function and stop the iteration immediatelly.
}
});
return result; //This will exit the function with return true;
}
"each" uses callback function.
Callback function execute irrespective of the calling function,so it is not possible to return to calling function from callback function.
use for loop if you have to stop the loop execution based on some condition and remain in to the same function.
I use this way (for example):
$(document).on('click', '#save', function () {
var cont = true;
$('.field').each(function () {
if ($(this).val() === '') {
alert('Please fill out all fields');
cont = false;
return false;
}
});
if (cont === false) {
return false;
}
/* commands block */
});
if cont isn't false runs commands block
When submit the form it runs both means to say code inside if is running and after else code is also running.
$("#new_chq").submit(function(){
var inputs = document.getElementsByName("val_2[]");
var i;
for (i = 1; i <= inputs.length; i++) {
$('#file_'+i).each(function() {
if(!$('#file_'+i).val() == ''){
$('#text_'+i).attr('required', '');
return false;
}
else{
return true ;
}
});
}
});
As you can see in docs:
We can break the $.each() loop at a particular iteration by making the
callback function return false. Returning non-false is the same as a
continue statement in a for loop; it will skip immediately to the next
iteration.
So, you need to move the form event handling after the jQuery each-loop.
Here is an example:
$("#new_chq").on('submit', function() {
var isValid = true;
$('[id^=file_]').each(function() {
if($(this).hasAttr('required') && !$(this).val()) {
isValid = false;
return false; // <- this breaks the loop
};
});
return isValid;
});
Please note, there are other errors in your code, such as $('#file_'+i).each loop, which has no sense - that is one element with unique id.
I am fairly new to JavaScript and I have a question regarding how to optimise if statements.
I will show you two scenarios.
//first
var number = 10;
var calculationOneResult = functionOne(number);
var calculationTwoResult = functionTwo(number);
if (calculationOneResult === true) {
//stuff
} else if (calculationTwoResult === true) {
//more stuffs
}
//second
var number = 10;
if (functionOne(number) === true) {
//stuff
} else if (functionTwo(number) === true) {
//more stuffs
}
Here is my question:
In the first scenario, I am calculating two times.
In the second one, if the first function returns true, will it calculate the second elseif statement or will it skip it after doing the stuff ?
The following code:
if(statement1) {
// stuff
} else if(statement2) {
// other stuff
}
is equivalent to
if(statement1) {
// stuff
} else {
if(statement2) {
// other stuff
}
}
as there is no elseif in JavaScript - see documentation.
So the answer is any function in statement2 will be simply skipped.
Nothing in an else clause executes if the if expression tests as true, so the second version of your code will definitely save a function call in such cases.
I have a loop that runs indefinitely until I tell it to stop. I am actually using requestAnimationFrame and a lot more is going on, but the below example is just to simplify my question.
var _stop = false;
var loop = function () {
while (!_stop) {
if (some condition is met) {
stop();
}
/* Do something. */
loop();
}
};
function stop() {
_stop = true;
}
Now this all works great, but it will still run /* Do something */ one more time before it actually stops. I want it to stop immediately and return.
Of course this can be done like so:
if (some condition is met) {
stop();
return;
}
But is there a way to include the return part into stop();? This doesn't do what I want for obvious reasons:
function stop() {
_stop = true;
return;
}
But is there a way to achieve this?
var _stop = false;
try {
var loop = function () {
if(!_stop) {
if (some condition is met) {
stop();
}
/* Do something. */
loop();
}
};
} catch(e) {
}
function stop() {
_stop = true;
throw new Error("USE IT WITH PRECAUTION");
}
The loop above does you job of exiting entire loop, But I will say its horribly wrong way of doing thing as ideally function should be
1) mutating the state variables
2) or should be computing the values.
3) or should be determining error state to stop the execution further
It should never be bothered about how the control flow of function caller is and ways to stop function caller execution flow.
It sounds like you want to check the condition (before) every time the work is done. To do this with a _stop variable (as opposed to simply checking the condition in the while condition itself), you have to:
Set the variable based on the condition before starting the loop
Do your work
Set the variable based on the condition before the next loop iteration
Whether you accomplish this with a while() loop or a do while() loop, the process will be the same. Adding a pre-loop check to your example will prevent the work from being done if the user has already exited:
var _stop = false;
// Call loop() when required
var loop = function () {
// Check condition before first iteration
if (/* some condition is met */) {
stop();
}
while (!_stop) {
/* Do your work */
// Check condition before every subsequent iteration
if (/* some condition is met */) {
stop();
}
loop();
}
};
function stop() {
_stop = true;
}
Is there a reason you are recursively calling loop() instead of calling it once and doing all of your work within the contained loop until the user exits? This more simplified version might work for you:
var _stop = false; // Set it initially, could also use checkStopRequired() here
// Call loop() when required
var loop = function () {
// Check condition before first iteration
_stop = checkStopRequired();
while (!_stop) {
// Do your work, setting _stop to true if work returns early
_stop = !doMyWork();
// Check condition before every subsequent iteration
_stop = checkStopRequired();
}
};
function checkStopRequired() {
// Return true if should stop, false if should continue
}
When doing the work required for each loop iteration, you may want to check the exit condition before any expensive operations to allow the whole thing to halt as soon as an exit condition is met, as opposed to waiting for the work to finish. This obviously depends on what work you're doing and what the exit conditions are.
An example of the function to be called within the loop, which will help you set _stop if the stop condition is met part-way through:
function doMyWork() {
// Get user input here...
if (checkStopRequired()) { return false; }
// Get data here...
if (checkStopRequired()) { return false; }
// Do logic here...
if (checkStopRequired()) { return false; }
// Render objects here...
// Return successful result
return true;
}
it might not be the optimal way to do this, but this can be done like this:
var _stop = false;
var flag=0;
var loop = function () {
if(!_stop) {
if(flag){
return;
}
if (some condition is met) {
stop();
_stop = true;
loop();
}
/* Do something. */
loop();
}
};
function stop() {
//_stop = true;
toReturn();
}
function toReturn(){
flag=1;
}
I have a function which accepts a string and outputs it one character at a time with a delay. The event occurs when the user clicks a link or button. The problem is that if the user clicks a link and then another before the first one is done, they both run at the same time and output to the screen. It becomes jumbled up.
ex:
string1 : "i like pie very much"
string1 : "so does the next guy"
output : i sloi kdeo epse .... and so on.
Anyone know a method to fix this?
I think I need a way to check if the function is being processed already, then wait till it is done before starting the next.
Place both functions inside an object (because globals are bad), add a variable to the object which knows if a function is executing, and check the variable, like this:
var ns = {
isExecuting:false,
func1: function(){
if (this.isExecuting) { return; }
this.isExecuting = true;
//do stuff 1
this.isExecuting = false;
},
func2: function(){
if (this.isExecuting) { return; }
this.isExecuting = true;
//do stuff 2
this.isExecuting = false;
}
}
and for extra elegance:
var ns = {
isExecuting:false,
executeConditionally:function(action){
if (this.isExecuting) { return; }
this.isExecuting = true;
action();
this.isExecuting = false;
}
func1: function(){
this.executeConditionally(function(){
//stuff
})
},
func2: function(){
this.executeConditionally(function(){
//stuff
})
}
}
add a variable globally or in scope outside the method called IsProcessing and set it to true the first time the method is called, on the method you can then just check if (IsProcessing) return false;
All you need to do is set a variable that indicates whether the function is running:
var isRunning = false;
$('a').click(function({
if(isRunning == false){
isRunning = true;
///Do stuff
isRunning = false;
}
else{
return false;
}
});
Don't you want all the clicks to be taken into account, but in order ?
If so, I suggest you separate streams between adding a click to process, and consuming clicks
:
the html :
<a class="example" href="javascript:void(0)" onclick="delayPushLine();">i like pie very much</a><br/>
<a class="example" href="javascript:void(0)" onclick="delayPushLine();">so does the next guy</a>
<div class="writeThere"></div>
and the javascript (using jQuery a bit)
var charDisplayDelay = 50; // the time between each char display
var displayDelay = 2000; // the time before a click is handled
var lines = [];
var lineIdx = 0, pos = 0;
function delayPushLine(e) {
if (!e) {
e = window.event
}
setTimeout(function() { lines.push(e.srcElement.innerText); }, displayDelay);
}
function showLines () {
if (lines.length > lineIdx) {
if (pos < lines[lineIdx].length) {
$(".writeThere").append(lines[lineIdx].substr(pos,1));
pos++;
} else {
pos = 0;
lineIdx++;
$(".writeThere").append("<br/>");
}
}
}
setInterval("showLines()", charDisplayDelay);
http://jsfiddle.net/kD4JL/1/