React 16.6 提供的一个新的开放一部分功能的 Suspense
代码
import React, { Suspense, lazy } from 'react'

const LazyComp = lazy(() => import('./lazy.js'))

let data = ''
let promise = ''
function requestData() {
if (data) return data
if (promise) throw promise
promise = new Promise(resolve => {
setTimeout(() => {
data = 'Data resolved'
resolve()
}, 2000)
})
throw promise
} function SuspenseComp() {
const data = requestData() return <p>{data}</p>
} export default () => (
<Suspense fallback="loading data">
<SuspenseComp />
<LazyComp />
</Suspense>
)

首先我们看到 export 出去的这个组件,他是一个 function component。然后他使用了 Suspense 。然后给他一个 props ,fallback,fallback 里面就是我们一开始看到的 loading data 。然后里面是两个组件

其中 SuspenseComp 也是一个 function component,调用了一个 requestData 。 渲染的是一个 p 标签,然后值是 {data} 。按照这么来讲的话,Suspense 为什么要提供一个 fallback 。一开始显示 loading data,过一份再显示内容呢。这就跟 requestData 有关系了。 requestData 里面先判断是否有 data 和 promise 。这里如果有 promise ,throw 这个 promise 。注意这里是 throw promise。这个 promise 里面是过 2s ,然后对 data 进行赋值。并且把这个 promise 给 resolve 。然后同样也要 throw promise 。
结合我们看到的 demo 的样子可以猜想,一开始运行程序,显示loading data。 过了 2s 后,有 data 和 promsie 了,重新进行渲染,这个时候就显示出了这个 p 标签。这就是 Suspense 执行的过程。
我们在 Suspense 下面渲染了一个或者多个这种异步的组件,有任何一个抛出了 promise ,在这个 promise resolve 之前,都会显示这个 fallback . 这就是 Suspense 最主要的一个原理的功能,用我们的大白话讲出来,当然他具体的实现是非常复杂的。
react 还支持一个方法 lazy,他可以让我们非常方便的实现一个异步组件加载,配合 webpack 可以很方便的实现这个功能。
lazy.js
import React from 'react'

export default () => <p>Lazy Comp</p>

有了这个组件之后,在 index.js 里面实现异步加载就变得非常的简单

const LazyComp = lazy(() => import('./lazy.js'))

调用 lazy , 传入一个方法,里面 import lazy.js。 Lazy Comp 跟 Data resolved 是一起显示出来的,那么这就是 Suspense 的一个特点,在 Suspense 内部有多个组件,他要等所有组件都 resolve 之后,他才会把 fallback 去掉,然后显示出这里面的内容,有任何一个还处于 pending 状态的,那么他还是会显示 fallback .

接下来看一下这两块的源码,打开 React.js,我们发现 Suspense 还是一个常量,是一个 Symbol,叫 REACT_SUSPENSE_TYPE 。然后 lazy ,lazy 就不是一个 Symbol 了。打开 ReactLazy.js
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/ import type {LazyComponent, Thenable} from 'shared/ReactLazyComponent'; import {REACT_LAZY_TYPE} from 'shared/ReactSymbols'; export function lazy<T, R>(ctor: () => Thenable<T, R>): LazyComponent<T> {
return {
$$typeof: REACT_LAZY_TYPE,
_ctor: ctor,
// React uses these fields to store the result.
_status: -1,
_result: null,
};
}

发现 ReactLazy.js 里面的源码也非常简单,lazy 是一个方法,然后他接收一个方法,并且返回一个 Thenable ,Thenable 什么意思呢?就是 promise 这样的一个对象。具有 .then , 而且这个 .then 是个 function 。他接收这个参数,他返回的是一个 LazyComponent 。返回的一个对象,里面有 $$typeof, 是 REACT_LAZY_TYPE。第一个返回的是 _ctor,这个 _ctor 就等于传进来的参数,这个方法,第三个 _status,这个是用来记录 Thenable 的一个状态的,因为在 react 渲染当中,在渲染到 LazyComponent 的时候,他会去调用这个 ctor 。然后返回一个 Thenable 的对象,一般来说我们认为他是一个 Promise , 这个时候 Promise 是属于 pending 状态的,对应的是 -1 。后面到 resolve 或者 reject 的时候,这个 _status 会变化,_result 是用来记录这个对象 resolve 之后返回的那个属性,lazy 里面最终返回出来的组件会放到

_result 里面,后续渲染 lazy 组件的时候,直接渲染 _result 里面的这个组件就好了

最新文章

  1. 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
  2. Linux - 变量
  3. 一个PHP混淆后门的分析
  4. Android系统用于Activity的标准Intent
  5. noip赛前小结2
  6. 4-3 yum命令
  7. E8.ITSM IT运维服务管理系统
  8. centos 给鼠标右击添加 “打开终端” 菜单项
  9. 克隆虚拟机后修改MAC地址
  10. XSL相关
  11. java transient修饰符
  12. MyBatis的类型自定义映射
  13. Python爬虫基本原理
  14. 一文了解Python的线程
  15. 基于stm32的水质监测系统项目基础部分详细记录
  16. cp备份操作时如何忽略指定的目录
  17. scrapy 简单爬虫实验
  18. 2016年3月10日Android实习日记
  19. c++ vector常见用法
  20. 前端开发VScode常用插件

热门文章

  1. failed to execute /bin/bash: Resource temporarily unavailable的问题处理
  2. wkhtmltopdf cpdf HTML转pdf 及pdf合并
  3. 终于有人把elasticsearch原理讲通了
  4. SCIE和SCI
  5. 第十二节:Asp.Net Core 之分布式缓存(SQLServer和Redis)
  6. 模拟 + 暴搜 --- Help Me with the Game
  7. VueTreeselect出现unknown解决方法
  8. CLH lock 原理及JAVA实现
  9. STM32Cube基础工程配置
  10. springMVC 任意文件读取相关路径