Location>code7788 >text

A Deeper Chat About async & Promise

Popularity:718 ℃/2024-12-17 23:35:18

main body (of a book)

Recently in the study of JavaScript async, await asynchronous, for which the Promise state as well as the actual running state of the Js engine behind not quite understand and is very interested in, so spent a little time to study carefully.

From Example

const createImg = function (path) {
  return new Promise((resolve, reject) => {
    const img = ('img');
     = path;
    ('images');
    ('load', () => {
      (img);
      resolve(img);
    });

    ('error', () => {
      reject(new Error('image has not found!'));
    });
  });
};

const loadImg = async function(imgPath){
	const imgs = (async img => await renderImg(img));
	(imgs);  // Question
}

loadImg(['./img/', './img/', './img/'])

Where imgPath is an array of image addresses, loadImg is an asynchronous function that traverses the rendered image, and renderImg is an asynchronous function that inserts and renders the image on the current page. My questions start with Question Line.Why does the console print out Promise < fulfilled: undefined>.

async mechanism

I started to learn from async's execution logic in the Js engine: async willOpen a separate concurrent programand when execution reaches one of the await lines (The premise is to return the Promise) when placing the post-await expression into the background of the Web APIs to run.

Following this execution logic analysis, loadImg first opens aloadImg programand a separate concatenation for each of the img asynchronous functions is created when executing to the (async img...) line, separate co-processes are created for each of the img asynchronous functions, which are referred to later for convenience asimg1, img2, img3 Concurrent Programs

The arrows in the figure indicateWhich program is currently executing in CALLSTACK?code content, since createImg in await createImg(img) is an asynchronous function that returns a Promise, it puts createImg into the Web APIs and immediately returns a Promise < pending >.

[!NOTE]

It's worth noting here that the Promise< pending> returned by createImg isReturns inside the Img coprocesswhich means that if there is a variable that can receive it, e.g. const tmp = await createImg(img), then thisPromise is assigned to tmp.However.A Promise< pending > object is returned immediately after the async call.(Later on, we describe in detail why the printout is Promise< fulfilled: undefined >, which is different).

Eventually you can see that 3 Promise< pending > objects are returned at the LoadAll concert, but what comes out is still Promise< fulfilled: undefined>, which is strange.

I reflect that there may be two problems:

  1. createImg(img) was too responsive, which led to it being FULFILLED by the time it switched between different co-processes;
  2. Or maybe async returns always Promise< fulfiiled>?
const loadAll = async function (ImgArr) {
  const imgs = (async Img => {
    ('start rendering');
    await new Promise(resolve => setTimeout(resolve, 2000));
    await createImg(Img);
    ('end rendering');
    return Img;
  });
  (imgs);
};

This time I put a 2s block before createImg so I can tell who's problem it really is.

The result is still Promise< fulfilled: [[value]]>? It's a bit confusing to be honest.
Rationally analyzed, thePromise is returned instantly, so there's no looking at subsequent code to see if it runs through, if there are bugs, etc., so theoretically you can justTroubleshooting issue 2Because generally speakingPending can go to both fullfilled/reject states.
After my many attempts, I found...

console console rendering in real time

Straight to the conclusion:

PromiseWhat is returned is Promise< pending>.and can only return this object, where the fullfilled /reject state is when the async in theAfter the asynchronous code background runsReturns to console withIt is up to the console to dynamically render the replaced

Evidence:

Clicking on the array of Promise objects in the console during the 2s period of blocking, you can see that in theThe whole async code didn't run.The time when eachPromises are all in the pending stateWait 2s.After the blocking periodBecause createImg is very fast, the dynamic rendering of the state from pending ->fullfilled can be replaced by the console in one go.

concern

None

summarize

So far the case is solved, and it has also helped me to understand the mechanism of async, Promise, and await a little better.