Yielding to Tasks Using await

node v14.20.1
version: 13.0.0
endpointsharetweet
Because JavaScript doesn't use a preemptive scheduler, CPU-intensive tasks must yield periodically in order to avoid starving other tasks.
async function a() { // wait for b to start await new Promise((resolve)=>setImmediate(resolve)); for (let i = 0; i <= 10000000; i++) { await new Promise((resolve)=>resolve()); } console.log('a() finished'); } async function b() { console.log('b() started'); for (let i = 0; i <= 5; ++i) { // do something... await new Promise((resolve)=>setImmediate(resolve)); } console.log('b() finished') } await Promise.all([a(), b()]);
In the above example, a() yields to b() which yields back to a(). a() then prevents b() from running despite using the await keyword in its loop. In the next example, a2() yields to b2(). Then b2() hogs the CPU until it finishes.
async function a2() { console.log('a2() started'); await new Promise((resolve)=>setImmediate(resolve)); console.log('a2() finished'); } async function b2() { for (let i = 0; i <= 1000; ++i) { // do something await new Promise((resolve)=>resolve()); } console.log('b2() finished'); } await Promise.all([a2(), b2()]);
The await keyword runs other tasks only when the Promise function performs a blocking operation. This, to yield to other tasks, use the following idiom: await new Promise((resolve)=>setImmediate(resolve)) JavaScript's unrelated yield operator is for emitting data from generator functions. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield.
Loading…

no comments

    sign in to comment