Related
I want to change my HTML before the js code is ended.
I tried to use async functions but i'm not sure if this is the correct way to do this.
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
function one() {
wait(1000);
document.getElementById("1a").innerHTML = "bla";
}
function two() {
wait(1000);
document.getElementById("2b").innerHTML = "blabla";
}
function three() {
wait(1000);
document.getElementById("3c").innerHTML = "blablabla";
}
function start() {
one();
two();
three();
} start();
the code waits 3 seconds and then update my divs.
I want my code to:
wait 1 second,
update div,
wait 1 second,
update div,
wait 1 second,
update div
You could try to use setTimeout.
Using a Function
I made this function which makes it easy to supply an array of objects you want to update.
/*
timed_elemet_updates(array, int)
`elements` should be an array of objects which contains the
ID and HTML you want to update.
*/
function timed_element_updates(elements, seconds) {
var element = elements.shift();
document.getElementById(element.id).innerHTML = element.html;
setTimeout(timed_element_updates, (seconds * 1000), elements, seconds);
}
Sample usage:
function start() {
var elements = [
{id: '1a', html: 'bla'},
{id: '2b', html: 'blabla'},
{id: '3c', html: 'blablabla'},
];
timed_element_updates(elements, 1);
}
start();
This answer is more concise (less repeating lines of code), easier to use (just add more elements to the array), and more reusable (no new function for every element)
Original Answer
function one() {
document.getElementById("1a").innerHTML = "bla";
setTimeout(two, 1000);
}
function two() {
document.getElementById("2b").innerHTML = "blabla";
setTimeout(three, 1000);
}
function three() {
document.getElementById("3c").innerHTML = "blablabla";
}
one();
This will call function one(), then it will call two() after 1000 milliseconds (1 second), then it will call three() after 1000 milliseconds (1 second).
That's solvable with Promises:
function showTextAfterMS (text, elemSelector, ms) {
return new Promise((res, rej) => {
let elem = document.querySelector(elemSelector);
if (!elem) {
return rej(new Error(`Cannot find element by selector: ${elemSelector}`));
}
setTimeout(() => {
elem.innerHTML = text;
res(elem);
}, ms);
});
}
showTextAfterMS('bla', '#el1', 1000).
then(() => showTextAfterMS('blabla', '#el2', 1000)).
then(() => showTextAfterMS('blablabla', '#el3', 1000));
<div id="el1"></div>
<div id="el2"></div>
<div id="el3"></div>
You could also do it with setTimeout or setInterval, but my experience is that using Promise is a bit more reliable/stable.
To show the first text without delay, just change the first call to showTextAfterMS to be showTextAfterMS('bla', '#el1', 0).
Edit
The reason why using Promises is the right solution is ultimately rooted in the runtime concepts of JavaScript. In short terms, it is because technically setTimeout as well as setInterval are both asynchronous actions, because they are both handled by the JavaScript event loop. A thorough explanation of the event loop and the general concurrency model of JavaScript can be found on MDN.
In short: Every action that has to be performed is pushed to the end of a Queue of actions the runtime has to, ... well, run. This way, actions from the UI are processed as well as other actions like timeouts and intervals. The runtime processes these actions step by step, however, they might need a different time to complete. That's because the runtime runs-to-completion, which means every action is processed after the precious action has been processed completely. Because actions produced by setTimeout as well as setInterval are placed onto the Queue, the amount of milliseconds isn't the guaranteed time the corresponding functions are called. It is a guaranteed minimal amount of time which elapses before they are being executed. This makes both of them produce asynchronous actions.
However, from an architectural point of view, what you need is a reliable and scalable way to sequence asynchronous actions. That's where Promises come into play.
Hand waving a bit, we can say that we can arrive at the same solution without Promise by using callback functions, because of the way the event loop works. It already calls one function at a time, right? So here is an "equal" solution based on callbacks:
// A "Promise equivalent", setTimeout based function with callbacks
function showTextAfter (ms, text, elemSelector, onComplete, onError) {
if (typeof ms !== 'number' || isNaN(ms)) {
return onError(new Error(`MS needs to be number, got: ${ms}`));
}
if (typeof text !== 'string') {
return onError(new Error(`Expected TEXT to be String, got: ${text}`));
}
let elem = document.querySelector(elemSelector);
if (!elem) {
return onError(new Error(`Cannot find element: ${elemSelector}`));
}
setTimeout(() => {
elem.innerHTML = text;
onComplete(elem);
}, ms);
}
showTextAfter(1000, 'bla', '#el1', (elem1) => {
showTextAfter(1000, 'blabla', '#el2', (elem2) => {
showTextAfter(1000, 'blablabla', '#el3', (elem3) => {
// do whatever you want with the elements. this example
// discards them
});
});
});
<div id="el1"></div>
<div id="el2"></div>
<div id="el3"></div>
It works equally well and allows you to chain your actions in a reliable way. The downsides of it are:
It doen't scale very well. To chain more actions, you need a deeper nesting, because new actions have to be called inside the success callback function.
You have to do that nesting by hand. Therefor, the deeper you have to nest, the harder it becomes to keep track of your code flow. That's why people call it the "pyramid of doom". Imagine having to blend in text for 20 elements.
Look at the signature of it: showTextAfter :: Number -> String -> String -> Function -> Function -> undefined. That's a lot of stuff for that measly little function! Wouldn't it be cool to just pass in the first 3 arguments?
We can mitigate the last problem somewhat by returning a new function from the call to showTextAfter, which consumes the onComplete and onError callbacks:
function showTextAfter (ms, text, elemSelector) {
return function (onComplete, onError) { // <-- this little fellow here is what it's all about
if (typeof ms !== 'number' || isNaN(ms)) {
return onError(new Error(`MS needs to be number, got: ${ms}`));
}
if (typeof text !== 'string') {
return onError(new Error(`Expected TEXT to be String, got: ${text}`));
}
let elem = document.querySelector(elemSelector);
if (!elem) {
return onError(new Error(`Cannot find element: ${elemSelector}`));
}
setTimeout(() => {
elem.innerHTML = text;
onComplete(elem);
}, ms);
}
}
const showEl1 = showTextAfter(1000, 'bla', '#el1');
const showEl2 = showTextAfter(1000, 'blabla', '#el2');
const showEl3 = showTextAfter(1000, 'blablabla', '#el3');
showEl1(elem1 => {
showEl2(elem2 => {
showEl3(elem3 => {
// whatever
});
});
});
<div id="el1"></div>
<div id="el2"></div>
<div id="el3"></div>
Yes, that's better. But, it doesn't really solve the problem, right?
Don't panic though, because these are exactly the problems Promises solve! They allow you to sequence asynchronous actions in a scalable way with much easier to track control flow. All the problems above can be removed by having a (native) "in place" return value to which you can "chain" other asynchronous steps which will complete "in the future" (meaning they can complete successfully or they can complete with an Error). The really smart thing is, that Promise allows you to chain the next asynchronous action without nesting.
See my initial (a bit altered) answer:
function showTextAfterMS (ms, text, elemSelector) {
return new Promise((onComplete, onError) => {
// type checking stuff...
let elem = document.querySelector(elemSelector);
setTimeout(() => {
elem.innerHTML = text;
onComplete(elem);
}, ms);
});
}
showTextAfterMS(1000, 'bla', '#el1'). // <-- no more nesting!
then(() => showTextAfterMS(1000, 'blabla', '#el2')).
then(() => showTextAfterMS(1000, 'blablabla', '#el3'));
<div id="el1"></div>
<div id="el2"></div>
<div id="el3"></div>
You can take advantage of async functions:
function one() {
console.log('document.getElementById("1a").innerHTML = "bla";')
}
function two() {
console.log('document.getElementById("2b").innerHTML = "blabla";')
}
function three() {
console.log('document.getElementById("3c").innerHTML = "blablabla";')
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
await sleep(1000);
one();
await sleep(1000);
two();
await sleep(1000);
three();
}
demo();
Ref: https://javascript.info/async-await
This function below doesn’t work like I want it to; being a JS novice I can’t figure out why.
I need it to wait 5 seconds before checking whether the newState is -1.
Currently, it doesn’t wait, it just checks straight away.
function stateChange(newState) {
setTimeout('', 5000);
if(newState == -1) {
alert('VIDEO HAS STOPPED');
}
}
Browser
Here's a solution using the new async/await syntax.
Be sure to check browser support as this is a language feature introduced with ECMAScript 6.
Utility function:
const delay = ms => new Promise(res => setTimeout(res, ms));
Usage:
const yourFunction = async () => {
await delay(5000);
console.log("Waited 5s");
await delay(5000);
console.log("Waited an additional 5s");
};
The advantage of this approach is that it makes your code look and behave like synchronous code.
Node.js
Node.js 16 provides a built-in version of setTimeout that is promise-based so we don't have to create our own utility function:
import { setTimeout } from "timers/promises";
const yourFunction = async () => {
await setTimeout(5000);
console.log("Waited 5s");
await setTimeout(5000);
console.log("Waited an additional 5s");
};
⚠️ Just for the record, you might be tempted to use a wait function to circumvent race conditions (when testing asynchronous code for example). This is rarely a good idea.
You have to put your code in the callback function you supply to setTimeout:
function stateChange(newState) {
setTimeout(function () {
if (newState == -1) {
alert('VIDEO HAS STOPPED');
}
}, 5000);
}
Any other code will execute immediately.
You really shouldn't be doing this, the correct use of timeout is the right tool for the OP's problem and any other occasion where you just want to run something after a period of time. Joseph Silber has demonstrated that well in his answer. However, if in some non-production case you really want to hang the main thread for a period of time, this will do it.
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
With execution in the form:
console.log('before');
wait(7000); //7 seconds in milliseconds
console.log('after');
I've arrived here because I was building a simple test case for sequencing a mix of asynchronous operations around long-running blocking operations (i.e. expensive DOM manipulation) and this is my simulated blocking operation. It suits that job fine, so I thought I post it for anyone else who arrives here with a similar use case. Even so, it's creating a Date() object in a while loop, which might very overwhelm the GC if it runs long enough. But I can't emphasize enough, this is only suitable for testing, for building any actual functionality you should refer to Joseph Silber's answer.
If you're in an async function you can simply do it in one line:
console.log(1);
await new Promise(resolve => setTimeout(resolve, 3000)); // 3 sec
console.log(2);
FYI, if target is NodeJS you can use this built-in function if you want (it's a predefined promisified setTimeout function):
import { setTimeout } from 'timers/promises';
await setTimeout(3000); // 3 sec
Use a delay function like this:
var delay = ( function() {
var timer = 0;
return function(callback, ms) {
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
Usage:
delay(function(){
// do stuff
}, 5000 ); // end delay
Credits: How to delay the .keyup() handler until the user stops typing?
You should not just try to pause 5 seconds in javascript. It doesn't work that way. You can schedule a function of code to run 5 seconds from now, but you have to put the code that you want to run later into a function and the rest of your code after that function will continue to run immediately.
For example:
function stateChange(newState) {
setTimeout(function(){
if(newState == -1){alert('VIDEO HAS STOPPED');}
}, 5000);
}
But, if you have code like this:
stateChange(-1);
console.log("Hello");
The console.log() statement will run immediately. It will not wait until after the timeout fires in the stateChange() function. You cannot just pause javascript execution for a predetermined amount of time.
Instead, any code that you want to run delays must be inside the setTimeout() callback function (or called from that function).
If you did try to "pause" by looping, then you'd essentially "hang" the Javascript interpreter for a period of time. Because Javascript runs your code in only a single thread, when you're looping nothing else can run (no other event handlers can get called). So, looping waiting for some variable to change will never work because no other code can run to change that variable.
setTimeout(function() {
$('.message').hide();
}, 5000);
This will hide the '.message' div after 5 seconds.
This solution comes from React Native's documentation for a refresh control:
function wait(timeout) {
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
}
To apply this to the OP's question, you could use this function in coordination with await:
await wait(5000);
if (newState == -1) {
alert('Done');
}
Try this:
//the code will execute in 1 3 5 7 9 seconds later
function exec() {
for(var i=0;i<5;i++) {
setTimeout(function() {
console.log(new Date()); //It's you code
},(i+i+1)*1000);
}
}
Best way to create a function like this for wait in milli seconds, this function will wait for milliseconds provided in the argument:
function waitSeconds(iMilliSeconds) {
var counter= 0
, start = new Date().getTime()
, end = 0;
while (counter < iMilliSeconds) {
end = new Date().getTime();
counter = end - start;
}
}
Based on Joseph Silber's answer, I would do it like that, a bit more generic.
You would have your function (let's create one based on the question):
function videoStopped(newState){
if (newState == -1) {
alert('VIDEO HAS STOPPED');
}
}
And you could have a wait function:
function wait(milliseconds, foo, arg){
setTimeout(function () {
foo(arg); // will be executed after the specified time
}, milliseconds);
}
At the end you would have:
wait(5000, videoStopped, newState);
That's a solution, I would rather not use arguments in the wait function (to have only foo(); instead of foo(arg);) but that's for the example.
You can add delay by making small changes to your function ( async and await ).
const addNSecondsDelay = (n) => {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, n * 1000);
});
}
const asyncFunctionCall = async () {
console.log("stpe-1");
await addNSecondsDelay(5);
console.log("step-2 after 5 seconds delay");
}
asyncFunctionCall();
If you have an asyn function you can do:
await new Promise(resolve => setTimeout(resolve, 5000));
99 times out of 100, this works perfectly:
function a(){
setInterval("b()",1000);
updateText("still working");
}
function b(){
timer++;
updateText(timer);
}
Occasionally the first loop waits for 20 seconds to 2 minutes. Thereafter it runs perfectly. I know the timer can pause on Android phones (when the soft keyboard is shown). Are there other conditions that might delay setInterval?
Firstly, it is strongly advised you provide a callback(function) as the first argument and not a string, because that string is evaluated in the global scope and we all know that bad things happen when we use eval in js (related eval post : When is JavaScript's eval() not evil?).
So, your
setInterval("b()", 1000);
should be rewritten as :
setInterval(b, 1000);
or:
setInterval(function() { b(); }, 1000);
I also recommend you use setTimeout to simulate a setInterval.
The main downfall of the setInterval function is that it executes a block of code every n milliseconds, regardless of the execution of the previous block of code.
So if for some reason a setInterval callback takes longer to execute than the delay provided, it will cause some stack overflows.
Let's take the following code for example :
function foo() {
// this takes about 2 seconds to execute
// .. code here
}
setInterval(foo, 1000);
This will actually freeze the browser because it will execute foo for an (almost) infinite number of times but it will never finish it.
The solution in this kind of case is to emulate the setInterval with setTimeout, in order to ensure that the callback has finished to execute before calling it again:
function foo() {
// this takes about 2 seconds to execute
// .. code here
}
function newSetInterval(callback, duration, callbackArguments) {
callback.apply(this, callbackArguments);
var args = arguments,
scope = this;
setTimeout(function() {
newSetInterval.apply(scope, args);
}, duration);
}
newSetInterval(foo, 1000);
Now, foo is called again only after the previous instance has finished the code execution.
I would apply the same thing to your code, in order to let the browser decide when it can execute the code, and not to force it to execute the block of code weather it's busy at that moment or not:
function a() {
newSetInterval(b, 1000);
updateText("still working");
}
function b() {
timer++;
updateText(timer);
}
function newSetInterval(callback, duration, callbackArguments) {
callback.apply(this, callbackArguments);
var args = arguments,
scope=this;
setTimeout(function() {
newSetInterval.apply(scope, args);
}, duration);
}
If you're interested, I've rewritten the setInterval and clearInterval functions in order to use them anywhere, without taking care of stack overflows :
function setInterval(f, time) {
setInterval.ids = setInterval.ids || {};
setInterval.idCount = setInterval.idCount || 0;
var that = this,
id = setInterval.idCount++,
// to prevent firefox bug that adds an extra element to the arguments
l = arguments.length - 2;
(function theFn() {
// to prevent firefox bug that adds an extra element to the arguments
var args = [].slice.call(arguments, 0, l);
f.apply(this, args);
setInterval.ids[id] = setTimeout.apply(this, [theFn, time].concat(args));
}).apply(that, [].slice.call(arguments, 2, arguments.length));
return id;
}
function clearInterval(id) {
if(!setInterval.ids || !setInterval.ids[id]) {
return false;
}
clearTimeout(setInterval.ids[id]);
return true;
}
try this,
setInterval(b, 1000);
or
setInterval(function(){
timer++;
updateText(timer);
}, 1000);
It's there a way to configure the setInterval method of javascript to execute the method immediately and then executes with the timer
It's simplest to just call the function yourself directly the first time:
foo();
setInterval(foo, delay);
However there are good reasons to avoid setInterval - in particular in some circumstances a whole load of setInterval events can arrive immediately after each other without any delay. Another reason is that if you want to stop the loop you have to explicitly call clearInterval which means you have to remember the handle returned from the original setInterval call.
So an alternative method is to have foo trigger itself for subsequent calls using setTimeout instead:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
This guarantees that there is at least an interval of delay between calls. It also makes it easier to cancel the loop if required - you just don't call setTimeout when your loop termination condition is reached.
Better yet, you can wrap that all up in an immediately invoked function expression which creates the function, which then calls itself again as above, and automatically starts the loop:
(function foo() {
...
setTimeout(foo, delay);
})();
which defines the function and starts the cycle all in one go.
I'm not sure if I'm understanding you correctly, but you could easily do something like this:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
There's obviously any number of ways of doing this, but that's the most concise way I can think of.
I stumbled upon this question due to the same problem but none of the answers helps if you need to behave exactly like setInterval() but with the only difference that the function is called immediately at the beginning.
Here is my solution to this problem:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
The advantage of this solution:
existing code using setInterval can easily be adapted by substitution
works in strict mode
it works with existing named functions and closures
you can still use the return value and pass it to clearInterval() later
Example:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
To be cheeky, if you really need to use setInterval then you could also replace the original setInterval. Hence, no change of code required when adding this before your existing code:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Still, all advantages as listed above apply here but no substitution is necessary.
You could wrap setInterval() in a function that provides that behavior:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
...then use it like this:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Here's a wrapper to pretty-fy it if you need it:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Set the third argument of setInterval to true and it'll run for the first time immediately after calling setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
Or omit the third argument and it will retain its original behaviour:
setInterval(function() { console.log("hello world"); }, 5000);
Some browsers support additional arguments for setInterval which this wrapper doesn't take into account; I think these are rarely used, but keep that in mind if you do need them.
Here's a simple version for novices without all the messing around. It just declares the function, calls it, then starts the interval. That's it.
//Declare your function here
function My_Function(){
console.log("foo");
}
//Call the function first
My_Function();
//Set the interval
var interval = window.setInterval( My_Function, 500 );
There's a convenient npm package called firstInterval (full disclosure, it's mine).
Many of the examples here don't include parameter handling, and changing default behaviors of setInterval in any large project is evil. From the docs:
This pattern
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
is identical to
firstInterval(callback, 1000, p1, p2);
If you're old school in the browser and don't want the dependency, it's an easy cut-and-paste from the code.
I will suggest calling the functions in the following sequence
var _timer = setInterval(foo, delay, params);
foo(params)
You can also pass the _timer to the foo, if you want to clearInterval(_timer) on a certain condition
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
For someone needs to bring the outer this inside as if it's an arrow function.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
If the above producing garbage bothers you, you can make a closure instead.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
Or maybe consider using the #autobind decorator depending on your code.
You can set a very small initial delay-time (e.g. 100) and set it to your desired delay-time within the function:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
To solve this problem , I run the function a first time after the page has loaded.
function foo(){ ... }
window.onload = function() {
foo();
};
window.setInterval(function()
{
foo();
}, 5000);
This example builds on #Alnitak's answer, but uses await Promise for finer granularity of control within the loop cycle.
Compare examples:
let stillGoing = true;
(function foo() {
console.log('The quick brown fox did its thing');
if (stillGoing) setTimeout(foo, 5000);
})();
foo();
In the above example we call foo() and then it calls itself every 5 seconds.
But if, at some point in the future, we set stillGoing to false in order to stop the loop, we'll still get an extra log line even after we've issued the stop order. This is because at any given time, before we set stillGoing to false the current iteration will have already created a timeout to call the next iteration.
If we instead use await Promise as the delay mechanism then we have an opportunity to stop the loop before calling the next iteration:
let stillGoing = true;
(async function foo() {
console.log('The quick brown fox did its thing');
await new Promise(resolve => setTimeout(resolve, 5000));
if (stillGoing) foo();
})();
foo();
In the second example we start by setting a 5000ms delay, after which we check the stillGoing value and decide whether calling another recursion is appropriate.
So if we set stillGoing to false at any point, there won't be that one extra log line printed after we set the value.
The caveat is this requires the function to be async, which may or may not be an option for a given use.
For Those using React, here is how I solve this problem:
const intervalRef = useRef(0);
useEffect(() => {
if (condition is true){
if (intervalRef.current === 0) {
callMyFunction();
}
const interval = setInterval(() => {
callMyFunction();
}, 5_000);
intervalRef.current = interval;
} else {
clearInterval(intervalRef.current);
}
}, [deps]);
// YCombinator
function anonymous(fnc) {
return function() {
fnc.apply(fnc, arguments);
return fnc;
}
}
// Invoking the first time:
setInterval(anonymous(function() {
console.log("bar");
})(), 4000);
// Not invoking the first time:
setInterval(anonymous(function() {
console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
console.log("baz");
}, 4000);
Ok this is so complex, so, let me put it more simple:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
If you can use RxJS, there is something called timer():
import { Subscription, timer } from 'rxjs';
const INITIAL_DELAY = 1;
const INTERVAL_DELAY = 10000;
const timerSubscription = timer(INITIAL_DELAY, INTERVAL_DELAY)
.subscribe(() => {
this.updateSomething();
});
// when destroying
timerSubscription.unsubscribe();
With ES2017, it may be preferable to avoid setInterval altogether.
The following solution has a much cleaner execution flow, prevents issues if the function takes longer than the desired time to complete, and allows for asynchronous operations.
const timeout = (delayMs) => new Promise((res, _rej) => setTimeout(res, delayMs));
const DELAY = 1_000;
(async () => {
while (true) {
let start_time = Date.now();
// insert code here...
let end_time = Date.now();
await timeout(DELAY - (end_time - start_time));
}
})();
There's a problem with immediate asynchronous call of your function, because standard setTimeout/setInterval has a minimal timeout about several milliseconds even if you directly set it to 0. It caused by a browser specific work.
An example of code with a REAL zero delay wich works in Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
You can find more information here
And after the first manual call you can create an interval with your function.
actually the quickest is to do
interval = setInterval(myFunction(),45000)
this will call myfunction, and then will do it agaian every 45 seconds which is different than doing
interval = setInterval(myfunction, 45000)
which won't call it, but schedule it only
I have the following scenario:
setTimeout("alert('this alert is timedout and should be the first');", 5000);
alert("this should be the second one");
I need the code after the setTimeout to be executed after the code in the setTimeout is executed. Since the code that comes after the setTimeout is not code of my own I can't put it in the function called in the setTimeout...
Is there any way around this?
Is the code contained in a function?
function test() {
setTimeout(...);
// code that you cannot modify?
}
In that case, you could prevent the function from further execution, and then run it again:
function test(flag) {
if(!flag) {
setTimeout(function() {
alert();
test(true);
}, 5000);
return;
}
// code that you cannot modify
}
I came in a situation where I needed a similar functionality last week and it made me think of this post. Basically I think the "Busy Waiting" to which #AndreKR refers, would be a suitable solution in a lot of situations. Below is the code I used to hog up the browser and force a wait condition.
function pause(milliseconds) {
var dt = new Date();
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}
document.write("first statement");
alert("first statement");
pause(3000);
document.write("<br />3 seconds");
alert("paused for 3 seconds");
Keep in mind that this code acutally holds up your browser.
Hope it helps anyone.
Using ES6 & promises & async you can achieve running things synchronously.
So what is the code doing?
1. Calls setTimeOut 1st inside of demo then put it into the webApi Stack
2. Creates a promise from the sleep function using the setTimeout, then resolves after the timeout has been completed;
3. By then, the first setTimeout will reach its timer and execute from webApi stack.
4. Then following, the remaining alert will show up.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
setTimeout("alert('this alert is timedout and should be the first');", 5000);
await sleep(5000);
alert('this should be the second one');
}
demo();
Just put it inside the callback:
setTimeout(function() {
alert('this alert is timedout and should be the first');
alert('this should be the second one');
}, 5000);
No, as there is no delay function in Javascript, there is no way to do this other than busy waiting (which would lock up the browser).
ES6 (busy waiting)
const delay = (ms) => {
const startPoint = new Date().getTime()
while (new Date().getTime() - startPoint <= ms) {/* wait */}
}
usage:
delay(1000)
You can create a promise and await for its fulfillment
const timeOut = (secs) => new Promise((res) => setTimeout(res, secs * 1000));
await timeOut(1000)
Here's a good way to make synchronous delay in your code:
async function yourFunction() {
//your code
await delay(n);
//your code
}
function delay(n) {
n = n || 2000;
return new Promise(done => {
setTimeout(() => {
done();
}, n);
});
}
Found it here Right way of delaying execution synchronously in JavaScript without using Loops or Timeouts!
setTimeout(function() {
yourCode(); // alert('this alert is timedout and should be the first');
otherCode(); // alert("this should be the second one");
}, 5000);
I think you have to make a promise and then use a .then() so that you can chain your code together. you should look at this article https://developers.google.com/web/fundamentals/primers/promises
You could attempt to replace window.setTimeout with your own function, like so
window.setTimeout = function(func, timeout) {
func();
}
Which may or may not work properly at all. Besides this, your only option would be to change the original code (which you said you couldn't do)
Bear in mind, changing native functions like this is not exactly a very optimal approach.