Reputation: 2484
I want to execute setTimeout after the delay and not wait for it to be called from the message queue after all the other functions have executed. Please refer the code below:
let test = function(){ console.log('test') }
setTimeout(() => console.log('hi'), 2000)
test();
test();
test();
.
.
.
.
this code takes more than 2 seconds to execute;
How to get setTimeout after 2 seconds instead of at the end ?
Upvotes: 3
Views: 1405
Reputation: 1235
I thought I would mention that if those test()
calls do not perform DOM operations you could possibly move them to a worker.
Web Workers allow running code on a background thread that doesn't block your main UI thread.
I've created a quick example that runs a synchronous task of arbitrary duration on a worker thread. On the main thread setInterval
and setTimeout
calls are running uninterrupted.
index.js
let interval = setInterval(() => console.log("Not blocked"), 500);
console.log("Scheduling to run in 2 seconds");
setTimeout(() => {
console.log("2 seconds passed. Running scheduled task! ");
}, 2000);
let longTaskRunner = new Worker("./src/worker.js");
let taskDuration = 3;
console.log(
`Starting synchronous task that takes more than ${taskDuration} seconds`
);
longTaskRunner.postMessage(taskDuration);
longTaskRunner.onmessage = function(e) {
console.log(`Long task completed in ${e.data} seconds`);
clearInterval(interval);
};
longTaskRunner.onerror = function(e) {
console.log(e.message);
};
worker.js
self.onmessage = function(e) {
const runFor = e.data * 1000;
let startedAt = Date.now();
let timeElapsed = 0;
while (timeElapsed < runFor) {
timeElapsed = Date.now() - startedAt;
}
self.postMessage(timeElapsed / 1000);
};
Upvotes: 1
Reputation: 370729
If the chain of test
s is consuming more than 2000ms of CPU time synchronously ("blocking"), I don't think it's possible like that - the best you could do is check in test
(or in a function wrapped around it) whether the time difference between the start (where your setTimeout
is currently) and the current time is more than 2 seconds - if so, execute the function. For example:
console.log('start');
let hasRun = false;
const fnToRunLater = () => console.log('hi');
const startTime = Date.now();
function test() {
const now = Date.now();
if (!hasRun && now - startTime > 2000) {
fnToRunLater();
hasRun = true;
}
for (let i = 0; i < 2e8; i++) {
// some expensive operations
}
}
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
if (!hasRun) {
fnToRunLater();
}
console.log('done');
(warning: below snippet containing the code above will block your browser for a bit, depending on your hardware)
// look at the timing in your browser console, not the snippet console
console.log('start');
let hasRun = false;
const fnToRunLater = () => console.log('hi');
const startTime = Date.now();
function test() {
const now = Date.now();
if (!hasRun && now - startTime > 2000) {
fnToRunLater();
hasRun = true;
}
for (let i = 0; i < 2e8; i++) {
// some expensive operations
}
}
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
test();
if (!hasRun) {
fnToRunLater();
}
console.log('done');
If an individual test
takes too long, and the timeout isn't accurate enough (eg, if a test takes 400ms and this takes the difference from 1800ms to 2200ms, and that 200ms of inaccuracy is too much), then you'll have to change the test
code so that it does multiple checks inside.
Upvotes: 0
Reputation: 50291
You may not need setTimeout
. Instead return a promise
from test
function and do rest of the things inside then
which will only work once test
is resolved
let test = function() {
return new Promise(function(resolve, reject) {
console.log('test');
resolve('test executed')
})
}
test().then(function(data) {
console.log(data)
});
Upvotes: 1