What if await had the same promise twice?

Time:2021-4-19

First look at the following interview question:

let counter = 0;
const increment = new Promise(resolve => {
  counter++;
  resolve();
});
await increment;
await increment;
console.log (counter); // what is the result?

You thinkcounterWhat is the value of?

What is promise? Does that mean “later”?

In fact, promise should be regarded as a state machine.

Promise starts its life cycle in the “pending” state. If you want to query results in this state, you must queue up.

According to the description in ECMAScript standard document(https://tc39.es/ecma262/), abovePromiseThe constructor immediately calls our executor function. itscounter++Side effect operation. Call without any parametersresolve()To store aundefinedAs a result, the state is promoted to “full”.

firstawaitfunction.awaitIt’s equivalent to running on your promise.then(onFulfilled), willonFulfilledSet to previous code. This work is queued as a micro task. JavaScript performs micro tasks in a first in first out order; controls the functions that are eventually returned to us.

the secondawaitThere’s nothing different. It creates a micro task, gives me the result of promise, runs the code ahead of time, and then waits for JavaScript to schedule.

The side effects are only inPromiseIt was run once during the build, socounterby1.

Are we putting off work? No, Promise is created and executed synchronously. But we used itawaitTo handle other micro tasks.

So how do you put off work?

const microtask = Promise.resolve()
.then(() => console.log('hello from the microtask queue'));

const macrotask = new Promise(resolve =>
  //Queue macro task
  setTimeout(() => {
    console.log('hello from the macrotask queue');
    resolve();
  })
  //No solution, promise is still in pending state
);

//This is the first output; We succeeded in putting off the work
console.log('hello from the original execution context');

//Yield scheduler; run. Then() and output log
await microtask;
//The state of yield scheduler is full, so there is no log output
await microtask;

//Yield scheduler; executes all micro tasks, then runs macro tasks and outputs logs
await macrotask;
//Yield scheduler; promise has been completed, so there is no log output
await macrotask;

PromiseConstructors run synchronously, but we don’t have to call them synchronouslyresolve()Promise.prototype.thenWork has also been delayed.

PromiseConstructors andPromise.prototype.thenThey don’t do the same thing.

This means promise can be used to remember asynchronous computation. If you use a promise and want to use its result again later, you should consider keeping itpromiseNot the result.

What if await had the same promise twice?


This article starts with WeChat official account: front-end pioneer.

Welcome to scan the two-dimensional code to pay attention to the official account, and push you every day to send fresh front-end technical articles.

What if await had the same promise twice?


Welcome to continue to read other high praise articles in this column: