I have been playing around with the feature in an SPA using TypeScript and native Promises, and I notice that even if I refactor a long-running function into an async function returning a promise, the UI is still unresponsive.
So my questions are:
How exactly does the new async/await feature help avoid blocking the UI in the browser? Are there any special extra steps one needs to take when using async/await to actually get a responsive UI?
Can someone create a fiddle to demonstrate the how async/await helps to make the UI responsive?
How does async/await relate to prior async features such as setTimeout and XmlHttpRequest?
await p
schedules execution of the rest of your function when promise p
resolves. That's all.
async
lets you use await
. That's (almost) all it does (It also wraps your result in a promise).
Together they make non-blocking code read like simpler blocking code. They don't unblock code.
For a responsive UI, offload CPU-intensive work to a worker thread, and pass messages to it:
async function brutePrime(n) {
function work({data}) {
while (true) {
let d = 2;
for (; d < data; d++) {
if (data % d == 0) break;
}
if (d == data) return self.postMessage(data);
data++;
}
}
let b = new Blob(["onmessage =" + work.toString()], {type: "text/javascript"});
let worker = new Worker(URL.createObjectURL(b));
worker.postMessage(n);
return await new Promise(resolve => worker.onmessage = e => resolve(e.data));
}
(async () => {
let n = 700000000;
for (let i = 0; i < 10; i++) {
console.log(n = await brutePrime(n + 1));
}
})().catch(e => console.log(e));