admin管理员组文章数量:1287535
I have this simple loop from 1-20. What I'm trying to do is to stop the loop using a button click. What I did is, I put a condition that upon button click the value of the variable stop
will be changed to 1, which will trigger the break
. But the value is not changed.
var stop = 0;
for(let i = 1; i <= 20; i++){
if(stop === 1){
break;
}
setTimeout(function(){
$('ul').append('<li>'+ i +'</li>');
},i * 500);
}
$('button').click(function(){
stop = 1;
});
ul li{
list-style-type: none;
float: left;
}
<script src=".1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
I have this simple loop from 1-20. What I'm trying to do is to stop the loop using a button click. What I did is, I put a condition that upon button click the value of the variable stop
will be changed to 1, which will trigger the break
. But the value is not changed.
var stop = 0;
for(let i = 1; i <= 20; i++){
if(stop === 1){
break;
}
setTimeout(function(){
$('ul').append('<li>'+ i +'</li>');
},i * 500);
}
$('button').click(function(){
stop = 1;
});
ul li{
list-style-type: none;
float: left;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
Share
Improve this question
edited Aug 30, 2018 at 9:26
Maor Refaeli
2,5372 gold badges21 silver badges34 bronze badges
asked Aug 30, 2018 at 8:03
user123user123
4431 gold badge7 silver badges23 bronze badges
6
- because your setTimeout are all triggered already – kevinSpaceyIsKeyserSöze Commented Aug 30, 2018 at 8:04
-
add a
console.log(i)
before yoursetTimeout
you'll see what I mean – kevinSpaceyIsKeyserSöze Commented Aug 30, 2018 at 8:06 -
if I change my if statement to this
if (i === 3) { break; }
it work. – user123 Commented Aug 30, 2018 at 8:06 - Yes because then you're breaking the loop on 3 – kevinSpaceyIsKeyserSöze Commented Aug 30, 2018 at 8:06
- That's what I'm trying to do break the loop – user123 Commented Aug 30, 2018 at 8:12
5 Answers
Reset to default 6The 20 setTimeout
functions were called before you even pressed on stop.
One of many ways to fix this is to check the stop
variable inside the function setTimeout
is executing.
var stop = 0;
for (let i = 1; i <= 20; i++){
setTimeout(function(){
console.log(stop);
if (stop !== 1) {
$('ul').append('<li>'+ i +'</li>');
}
},i * 500);
}
$('button').click(function(){
stop = 1;
});
ul li{
list-style-type: none;
float: left;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
Edit:
You ask how to stop the for
loop. The way it's written you can't.
This is how I would have implemented this in order to "stop" the loop with setTimeout
.
You can also do it with setInterval
(check Сергей Петрашко's answer to see a how).
Read about the differences between them here):
var stop = false;
function addNumberAndCallNext(number, max) {
if (!stop && number <= max) {
$('ul').append('<li>'+ number +'</li>');
setTimeout(addNumberAndCallNext.bind(null, ++number, max), 500);
}
}
addNumberAndCallNext(1, 20);
$('button').click(function(){
stop = true;
});
ul li {
list-style-type: none;
float: left;
padding-right: 5px;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
You can try next code without jQuery.
I don't reend to use --- $('ul').append('<li>'+ i +'</li>');
-
is bad practice.
true way --is create node before loop.
in this task you can use setIntrval instead of setTimout and loop
let itemList = (i) => {
let item = document.createElement('li');
item.value = i;
item.textContent = i;
return item;
}
let list = document.getElementById('list');
let stopButton = document.getElementById('stop');
let i = 0,
interval;
let reset = () => {
clearInterval(interval)
}
stopButton.addEventListener('click', () => {
reset()
});
interval = setInterval(() => {
list.append(itemList(i))
i++;
if (i > 20) reset()
}, 300)
<button id="stop">stop</button>
<br>
<ul id="list"></ul>
You can't stop a for loop by a click event because JavaScript is single threaded. The loop beginning
for(let i = 1; i <= 20; i++){
...
runs synchronously when executed without being interrupted by event handlers.
It will initiate 20 timer calls to be executed 500ms apart and return to the event loop before a click handler executes.
You have options to initiate the timer calls anyway and check the stop flag before adding an element, or set up some kind of asynchronous loop (e.g using setInterval
) that increments the i
variable and stops the timer callback if i
reaches a maximum or the click event occurs.
The issue is that the entire for loop has executed before you even had a chance at pressing the button. setTimeout doesn't actually sleep or block, but rather puts a new event and just continues in the for loop.
The browser, all its clocks for timeout purposes and so on can only run when your code has finished running for the time being. There is no thing equivalent to the sleep() function.
Maybe using async functions (ES2015 IIRC, should be supported by all current non-IE browsers), and awaiting for a promise created by util.promisify(setTimeout)(2000)
can be more intuitive.
There are no blocking functions. There is no sleeping inside code. All code basically runs on the CPU and sets up I/O and timer events which happen asynchronously, once the synchronous part has already finished.
JavaScript is unintuitive for this reason. However you may feel the value for asynchronicity once you have seen that you can get one kind performance this way. I mean... While JS code itself is executing the DOM cannot be checked by the browser. You cannot scroll, you cannot click, the mouse cursor itself won't change its kind. Only once a code block has finished will the browser handle all the pending events.
I would do this recursive. Then you have two break conditions stop and count === max.
var stop = false;
var print = function(count, max) {
setTimeout(function(){
if(stop){
return;
}else if(count === max){
return;
}else{
$('ul').append('<li>'+ count +'</li>');
return print(++count, max);
}
}, 500);
}
$('button').click(function(){
stop = true;
});
print(0, 20);
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
本文标签: javascriptStop for loop using break on clickStack Overflow
版权声明:本文标题:javascript - Stop for loop using break on click - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741305688a2371355.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论