“This is the 27th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

Wakeable,Thenable can’t tell the difference

import type {Wakeable, Thenable} from 'shared/ReactTypes';
export interface Wakeable {
  then(onFulfill: () = > mixed, onReject: () = > mixed): void | Wakeable;
}
export interface Thenable<+R> {
  then<U>(
    onFulfill: (value: R) = > void | Thenable<U> | U,
    onReject: (error: mixed) = > void | Thenable<U> | U,
  ): void | Thenable<U>;
}
import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';

REACT_LAZY_TYPE = symbolFor('react.lazy');
Copy the code
  • Wakeable, wakeable. Such an interface specifies that the class that implements it must implement onethenMethod, this onethenMethod returns a value of typevoid(empty) orWakeable. It takes two function arguments, a callback on success and a callback on failure.
  • ThenableInterfaces are defined withWakeableThe definition is similar, but the input parameters of the function are different.ThenabletheonFulfillThe return value of the method can beThenableWhich means you can go down infinitelythenGo on.
  • REACT_LAZY_TYPEThe identifier is identifiedreactLazy load type, read the source code you will knowreactWhat is the role of lazy loading types.

If not quite understand here, the proposal to continue to look down, mountain poor water doubt no way, another village, do not hang in this tree.

Q: How is Wakeable the same as Thenable?

Thenable status value

const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
const Rejected = 2;
Copy the code
  • Uninitialized: indicates that the initialization is Uninitialized and the value is -1.
  • Pending: indicates that the file is being loaded and the value is 0.
  • Resolved: indicates that the load is complete and successful. The value is 1.
  • Rejected: indicates that the load is complete but fails. The value is 2.

Is it really worth it?

So let’s say the Thenable method is going to return an unknown quantity, so what does that unknown quantity represent? Please read the following code:

type UninitializedPayload<T> = {
  _status: -1._result: () = > Thenable<{default: T, ...}>,
};

type PendingPayload = {
  _status: 0._result: Wakeable,
};

type ResolvedPayload<T> = {
  _status: 1._result: {default: T},
};

type RejectedPayload = {
  _status: 2._result: mixed,
};
Copy the code

Payloads are classified into four types based on state values.

  • UninitializedPayloadFor uninitialized payloads, the _result attribute returns a Thenable for a function.
  • PendingPayload, payload being loaded, _result attribute is a Wakeable.
  • The _result attribute is an object. The default value is the data type corresponding to the generic T.
  • RejectedPayload: payload that has failed. – The result attribute is mixed, indicating any type.

As you can see, in the Resolved phase, it will return an arbitrary data type mixed, which is returned by Wakeable after the _result property of the loading payload is executed. The _result attribute of the uninitialized payload returns a Thenable, which returns a Wakeable, a function that will return the actual data. The ResolvedPayload is the data we actually need.

Explosion, which simply returns data from an asynchronous call, is designed with four layers. Is it really worth it?

What der is cTOR


export function lazy(ctor) {
  const payload = {
    _status: Uninitialized,
    _result: ctor,
  };

  const lazyType = {
    $$typeof: REACT_LAZY_TYPE,
    _payload: payload,
    _init: lazyInitializer,
  };
  return lazyType;
}
Copy the code

Finally, React exports a lazy function and everything is fine.

What der is cTOR?

First, let’s look at the use of the react. lazy API.

const LazyComponent = React.lazy(() = > import('.. /componets/LazyComponent));Copy the code

As you can see, ctor is a function that returns an asynchronous call to Thenable.

function resolveLazy(lazyType) {
  const payload = lazyType._payload;
  const init = lazyType._init;
  return init(payload);
}
function lazyInitializer(payload) {
  if (payload._status === Uninitialized) {
    const ctor = payload._result;
    const thenable = ctor();
    thenable.then()
    ...
    }
Copy the code

The resolveLazy method calls the _init method of lazyInitializer and initially enters an uninitialized state. Calling ctor yields a thenable object. In an asynchronous call, the state of payload will be Pending. After the call, moduleObject.default is returned, returning the payload required for this component to render.

Asynchronous routes are not enough, and third-party packets also need to be asynchronous.

During the iteration of a project, as more and more modules are added, webPack will pack more and more third-party packages, causing the system to load more and more slowly for the first time. In spite of the asynchronous routing, adding too many files to the main.js file will cause the main entry file to be too large to a certain extent. React’s lazy approach is worth studying to deal with the problem of too many third party packages in a project.

Thanks for reading, and please use your little hands and give it a thumbs up.