阅读 200

react源码解读之ReactLazy.js

Wakeable,Thenable傻傻分不清楚

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'); 复制代码

  • Wakeable,可唤醒的。这样一个接口规定实现它的类,必须实现一个then方法,这个then方法的返回值类型为void(空)或者Wakeable。它接收两个函数参数,成功时的回调和失败时的回调。

  • Thenable接口的定义与Wakeable的定义类似,只是函数参数的入参不一样,ThenableonFulfill方法的返回值可以为Thenable,也就是说可以无限地往下then下去。

  • REACT_LAZY_TYPE标识符标识了react的懒加载类型,读完源码你会知道react懒加载类型有何作用。

如果这里不太明白,建议继续往下看,山穷水复疑无路,柳暗花明又一村,不要在这颗树上吊死了。

问题Wakeable与Thenable有何不一样?

Thenable的状态值

const Uninitialized = -1; const Pending = 0; const Resolved = 1; const Rejected = 2; 复制代码

  • Uninitialized,表示未初始化,值为-1。

  • Pending,表示正在加载中,值为0。

  • Resolved,表示已经加载完成并且加载成功,值为1。

  • Rejected,表示已经加载完成但是加载失败,值为2。

真的值得吗?

payload表示有效载荷,关键信息 假设Thenable方法会返回一个未知量,那么这个未知量代表什么呢? 请阅读下面的代码:

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, }; 复制代码

根据状态值,将有效载荷分为4种类型。

  • UninitializedPayload,未初始化的有效载荷,_result属性为一个函数返回一个Thenable。

  • PendingPayload,加载中的有效载荷,_result属性为一个Wakeable.

  • ResolvedPayload,已完成的有效载荷,_result属性为一个对象,默认值为泛型T对应的数据类型。

  • RejectedPayload,已失败的有效载荷,—result属性为mixed,表示任意类型。

可以看到,在Resolved阶段,返回的是任意数据类型(mixed),这个mixed又由Wakeable返回,也就是加载中有效载荷的_result属性执行后返回。未初始化的有效载荷的_result属性调用后,返回一个Thenable,这个Thenable会返回一个Wakeable,也就是将会返回实际数据的一个函数。ResolvedPayload就是我们实际所需要的数据。

爆炸,就简简单单的一个异步调用返回数据的功能,被设计成了四层。这真的值得吗?

ctor是个什么der

 export function lazy(ctor) {   const payload = {     _status: Uninitialized,     _result: ctor,   };   const lazyType = {     $$typeof: REACT_LAZY_TYPE,     _payload: payload,     _init: lazyInitializer,   };   return lazyType; } 复制代码

最后,react导出了一个lazy函数,万事大吉。

ctor是个什么der?

首先,我们看看React.lazy这个api的使用。

const LazyComponent = React.lazy(() => import('../componets/LazyComponent)); 复制代码

可以看到,ctor是一个函数,这个函数返回一个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()     ...     } 复制代码

resolveLazy方法会调用lazyInitializer的_init方法,最开始,会进入未初始化的状态判断。 调用ctor得到一个thenable的对象。在异步调用过程中,payload的状态将是Pending。 调用结束之后会返回moduleObject.default,返回这个组件渲染所必须的payload。

异步路由不够,第三方包也要异步。

在一个项目的迭代过程中,随着模块的越来越多,webpack打包的第三方包将会越来越多,这样导致系统首次加载将会越来越慢。虽然有了异步路由的加持,但是在main.js文件里加入过多的文件,项目大到一定程度,仍将导致主入口文件的体积过大。React的lazy方法值得我们学习,去处理项目第三方包过多的问题。

感谢阅读,欢迎动动你的小手,给个赞吧。

 伪原创工具 SEO网站优化  https://www.237it.com/ 

作者:cutekio
链接:https://juejin.cn/post/7035996414874222623

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐