function avoidAfterTime() {
var startTime = new Date().getTime();
var interval = setInterval(function () {
if (new Date().getTime() - startTime > 3000) {
clearInterval(interval);
console.log("more than 2 sec")
return;
}
longWorking();
}, 2000);
}
avoidAfterTime();
function longWorking(){
var t;
for (i = 0; i < 1e10; i++) t = i;
console.log(t);
}
Hello. I am very new to JS. But I need to stop running some function (here it is longWorking) which can be executed for few seconds or for so much time. And I want to abort the function in case of it takes too long. I guess I know how to make it using, for example, threads in some other programming language. But I have no idea about making it in JS. I thought in this way (above)... But it doesn't work. Can someone help me?
hmm, I drafted this example. So it's a function that runs every second and if it takes more than 6 seconds it will stop. So basically you can put your work load in the doSomething() function and let it work every second and stop it if it takes too long. Or you can stop it based on a value. It depends on what do you want to do with it. I used the module pattern to isolate the logic and the variables. So you can encapsulate your logic in a module like way.
(function() {
'use strict';
let timing = 0;
const interval = setInterval(doSomething, 1000);
function doSomething() {
timing++;
if (timing > 5) {
clearInterval(interval);
}
console.log('working');
}
})();
Is this something you are looking for?
Related
I'm building a program that either counts down or up and I've got it working however I like to press count-up in the middle of count down or vice versa and I like the counter to stop and count up or vice versa. how do I achieve that? thanks a lot for your help :)
function myFunctionUp() {
var Timer = setInterval(function () {
i++;
document.getElementById("mydata").textContent = i;
if (i >= 21)
clearInterval(Timer);
if (i == 21){
document.getElementById("mydata").textContent = "Boom-up!";
}
}, 1000);
}
function myFunctionDown() {
var Timer = setInterval(function () {
i--;
document.getElementById("mydata").textContent = i;
if (i <= 0)
clearInterval(Timer);
if (i == 0){
document.getElementById("mydata").textContent = "Boom-down";
}
}, 1000);
}
Use a variable to keep track of the way to count. When a button is clicked, invert the value of the variable :
let countDown = 10;
let increment = -1;
function count() {
countDown += increment;
document.getElementById('container').innerText = countDown;
setTimeout(() => count(), 1000);
}
document.getElementById('btn').addEventListener('click', function () {
increment = -increment;
});
count();
Working stackblitz here
You typically never "take control" on the execution of another method. When you want to do that, the logic must be inverted. The function itself must ask if it should continue.
With an example : let's take a function which works in an infinite loop, that you want to be able to stop on demand. In some languages, you could run some code in a thread and interrupt the thread on demand. But even if it is possible, it is generally a bad idea to stop some code at the middle of its execution.
A better way of doing that is to create a "should Continue ?" piece of code at the end of the iteration. It could read a variable or call a method etc. When you want to stop the iteration, you just have to set this variable and you know that the infinite loop will stop graciously at the end of the current iteration
I have a simple question about Javascript timers and their performance but it really bugs me because I can't figure out the right way to do it.
Here is the problem: I have a special timing function that self corrects itself:
function setCorrectingInterval(func, delay) {
if (!(this instanceof setCorrectingInterval)) {
return new setCorrectingInterval(func, delay);
}
var target = Date.now() + delay;
var self = this;
function tick() {
if (self.stopped) {
return;
}
target += delay;
func();
setTimeout(tick, target - Date.now());
}
setTimeout(tick, delay);
}
Then, in my application I use this function n times to set n different timer variables. So if I have two timer variables I would use this function twice to set them. In the code bellow I execute first task every 1000ms and second task every 2000ms:
var firstTimer,
secondTimer;
function startFirstTimer() {
firstTimer = setCorrectingInterval(function() {
console.log("First!");
}, 1000);
}
function startSecondTimer() {
secondTimer = setCorrectingInterval(function() {
console.log("Second!");
}, 2000);
}
startFirstTimer();
startSecondTimer();
In my angular application the need for multiple timing events grows and grows. So my (tempoprary) solution to this is to create new timer variables with new setTimeouts using the setCorrectingInterval function as mentioned above.
So I got thinking - wouldn't it be better (performance wise) to just have one single timer variable with one single setTimeout in which using if statements I would execute tasks that meet the condition, like this:
var timer;
function startTimer() {
var counter = 1;
timer = setCorrectingInterval(function() {
console.log("First!");
if (counter % 2 === 0) {
console.log("Second!");
}
counter++;
}, 1000);
}
startTimer();
( provided every tasks would repeat execution with delay that is multiple of 1000 )
Which approach is better and why? Any explanation is very much appreciated, thank you
I have a script that changes some values and clicks some buttons in a browser. I'm looking for a way to pause the execution of the code for x seconds without making the browser lag out. I'm using Firefox and I paste this script into its console. I'm aware of the setTimeout() function. However, this function doesn't stop executing the code, but rather waits x seconds till executing it. I'm looking for a complete solution that's similar to Python's time.sleep() function and pauses the execution of the code completely.
var init = 0.01
var start = init
var $odds = $("#oddsOverUnder")
var $button = $("#roll")
var $bet = $("#bet")
function roll(){
$bet.val(start)
$button.click()
//i want to pause the execution of the code here//
$button.click()
//and here//
refreshIntervalId=setInterval(roll2, 2000)}
function roll2(){
var tr = document.querySelector("#myBetsTable tr:nth-child(2)")
var cls = tr.getAttribute('class')
if (cls === 'success'){
start = init
$bet.val(start)}
else{
start = start * 2
$bet.val(start)
$odds.click()}
clearInterval(refreshIntervalId)
roll()}
roll()
There's no equivalent to Python's time.sleep() in JavaScript, which generally executes asynchronously by design. If you'd like to delay execution of code, you can use setTimeout, as you mentioned.
Without understanding exactly what your code is supposed to do, I can't suggest the ideal architecture for this problem. There's definitely a better way to do it than what I'm about to suggest. Still, to answer your question, you can simulate what you're asking this way:
function roll() {
$bet.val(start);
$button.click();
setTimeout(function () {
$button.click();
setTimeout(function () {
refreshIntervalId = setInterval(roll2, 2000);
}, 1000);
}, 1000);
}
How about setting timeouts inside a timeout?
function roll() {
$bet.val(start)
$button.click()
setTimeout(function() {
$button.click();
setTimeout(
function() {
$button.click();
refreshIntervalId = setInterval(roll2, 2000)
},
5000
);
},
5000
);
}
also, please see: https://stackoverflow.com/a/951057/2119863
var i = 3400;
function progress() {
i = 34000;
window.setInterval(function () {
i = i - 100;
document.getElementById("progress").firstChild.data = i;
}, 100);
}
This code is getting faster and faster. The function progress is called every 3 seconds, but I can't change the it's called because it's event based. After around 10 calls i is getting negative!
Umm....
Do not use setInterval
You probably want to use setTimeout
Since progress is called every 3 seconds, you need to avoid that it creates new intervals repeatedly. Using clearTimeout resets the timer anytime you call progress. However, without knowing what exactly you want to achive it's difficult to provide an accurate answer.
var timeout;
function counter(count) {
document.getElementById("progress").firstChild.data = count;
if (count >= 0) {
timeout = window.setTimeout(function() {
counter(count-100);
}, 100);
}
}
function progress() {
window.clearTimeout(timeout);
counter(3400);
}
Try this
var i = 3400;
function progress() {
i = i - 100;
document.getElementById("progress").firstChild.data = i;
window.setTimeout('progress();', 100);
}
I have a website where they want a news ticker. Currently, I have a array that populates it, and every x seconds, I want the news story to change.
function startNews(stories) {
}
I am aware that you can use setInterval, but it has to go through a new function and you can't specify certain javascript in the same function to fire when it does.
What are you suggestions?
Thanks!
You should use either setInterval() or repeated calls to setTimeout(). That's how you do something in javascript at some time in the future.
There are no limitations on what you can do with either of those timer functions. What exactly do you think you cannot do that is making you try to avoid them?
Here's a pseudo code example:
var newsArray = []; // your code puts strings into this array
var curNewsIndex = -1;
var intervalID = setInterval(function() {
++curNewsIndex;
if (curNewsIndex >= newsArray.length) {
curNewsIndex = 0;
}
setTickerNews(newsArray[curNewsIndex]); // set new news item into the ticker
}, 5000);
or it could be done like this:
var newsArray = []; // your code puts strings into this array
var curNewsIndex = -1;
function advanceNewsItem() {
++curNewsIndex;
if (curNewsIndex >= newsArray.length) {
curNewsIndex = 0;
}
setTickerNews(newsArray[curNewsIndex]); // set new news item into the ticker
}
var intervalID = setInterval(advanceNewsItem, 5000);
You should whenever possible use setTimeout. If your function takes longer to run than the interval, you can run into a constant 100% cpu usage situation.
Try this code:
http://jsfiddle.net/wdARC/
var stories = ['Story1','Story2','Story3'],
i = -1;
(function f(){
i = (i + 1) % stories.length;
document.write(stories[ i ] + '<br/>');
setTimeout(f, 5000);
})();
Replace document.write with your function.