I'm having trouble understanding how asynchronous code runs in javascript.
I have a code similar to the following:
const start = name => console.log(`${name} started`);
const finish = name => console.log(`${name} finished`);
const wrap = async (promise, name) => {
start(name);
const promiseResult = await promise;
finish(name);
return promiseResult;
}
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const inner = async ms => {
return await sleep(1000);
}
const outer = async ms => {
await wrap(inner(ms), 'inner1');
await wrap(inner(ms), 'inner2');
await wrap(inner(ms), 'inner3');
}
const testPromise = async promise => {
const t0 = performance.now();
const promiseResult = await promise;
const t1 = performance.now();
console.log(`Running promise took ${t1 - t0} milliseconds`);
return promiseResult;
}
testPromise(wrap(outer(5000), 'outer'));
The output of the above code is:
inner1 started
outer started
inner1 finished
inner2 started
inner2 finished
inner3 started
inner3 finished
outer finished
Running promise took 3026.2199999997392 milliseconds
As you can see in the output, inner1
was started before outer
started, which is very weird! What I expect is that all inner
calls start and finish within the start and finish of outer
.
I did a lot of research on Google but couldn't find anything helpful unfortunately.
What worked for me is to explicitly emulate wrap
function for outer
call like below:
const start = name => console.log(`${name} started`);
const finish = name => console.log(`${name} finished`);
const wrap = async (promise, name) => {
start(name);
const promiseResult = await promise;
finish(name);
return promiseResult;
}
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const inner = async ms => {
return await sleep(1000);
}
const outer = async ms => {
await wrap(inner(ms), 'inner1');
await wrap(inner(ms), 'inner2');
await wrap(inner(ms), 'inner3');
}
const testPromise = async () => {
const t0 = performance.now();
const outerName = 'outer'; // -- emulate calling `await wrap(outer(5000), 'outer')`
start(outerName); // --
const promiseResult = await outer(5000); // --
finish(outerName); // -- finished emulation of `wrap`
const t1 = performance.now();
console.log(`Running promise took ${t1 - t0} milliseconds`);
return promiseResult;
}
testPromise();
The output of the above code is what I really expect:
outer started
inner1 started
inner1 finished
inner2 started
inner2 finished
inner3 started
inner3 finished
outer finished
Running promise took 3155.5249999510124 milliseconds
What am I doing wrong that makes inner1
start before outer
is started?