Reputation: 7163
Maybe this is an async / await situation but I thought async was mainly for api calls(?)
How do you wait a long loop to finish, like this:
let x;
for (i = 1, i < 10000000000000000, i++) {
x += (i * 99999);
}
console.log(x);
Upvotes: 1
Views: 1168
Reputation: 14992
I thought async was mainly for api calls(?)
There are two different concepts related to the async
word:
async/await
functions
Syntax sugar for receive Promises results in syncronous mannerasync/await
function does not make your function execution asynchronous automagically.
const foo = async (i) => { console.log('foo running', i); return i == 0 ? 42 : await foo(i-1); };
console.log('foo before')
foo(5)
.then(x => console.log('foo', x))
console.log('foo after')
// foo before
// foo running 5
// foo running 4
// foo running 3
// foo running 2
// foo running 1
// foo running 0
// foo after
// foo 42
Javascript is one-threaded, all concurrent tasks must be splitted into async chunks to have any chance to other to work.
So, you should split your sync loop to many async parts to not to be frozen.
For example(I reduce params to have not too much time for wait):
async function calcX() {
let x = 0;
function iteration(i) {
x += (i * 99999);
if (++i >= 10000) return Promise.resolve(x);
return new Promise((resolve) => {
setTimeout(() => iteration(i).then(resolve), 0);
// or requestAnimationFrame
});
}
return await iteration(1);
}
const start = Date.now();
calcX()
.then(x => console.log(x, Date.now() - start), err => console.error(err));
// 4999450005000 42465
Or use WebWorker for your heavy sync task
Upvotes: 2
Reputation: 10906
You can convert long running synchronous functions into asynchronous functions by checking to see if a set amount of time has elapsed, and then coming back to the function later (achieved in this example via setTimeout
):
var lastBreak = Date.now()
function takeABreak() {
return new Promise(resolve=>setTimeout(resolve));
}
async function maybeTakeABreak() {
if (Date.now() - 17 > lastBreak) {
lastBreak = Date.now();
await takeABreak();
}
}
async function myLongLoop() {
let x = 0;
for (let i = 1; i < 100000000000000; i++) {
await maybeTakeABreak();
x += (i * 99999);
if (!(i%1000000)) {
console.log(i);
// alternatively you could run `await takeABreak();` here
}
}
return x;
}
myLongLoop().then(x=>console.log(x));
Upvotes: 1