将Promise转换成React的Suspense支持的数据结构

109 阅读1分钟

实现一个转换器,将Promise转换成React的Suspense支持的数据结构

如果觉得有用可以去我的github仓库给个star哦

仓库指路 promise-support-suspense

wrapPromise 的工作机制:

接收Promise作为参数

当Promise resolved , 返回 resolved value

当Promise rejected , 返回rejected value

当Promise pending , 返回Promise这个对象

暴露一个对应的read方法, 来读取Promise的状态

实现原理:

suspense内部有对内部组件状态的捕获机制, 如果是等待或者出现错误, 直接throw即可

如果Promise有数据就正常返回即可

转换器主体fetchData.tsx

 function wrapPromise(promise: Primise<any>) {
     //设置两个变量, 一个是表示当前状态的变量, 一个是结果变量
     let status = 'pending'
     let result : amy;
     //利用传入的promise改变自身状态
     suspender = promise.then((r) => {
         status = 'success',
         result = r
     }, (e) => {
         status = 'error',
         result = e
     })
     return({
         //将read包裹在对象中暴露出去
         read() {
             if(status === 'pending') throw suspender
             else if(status === 'error') throw result
             else if(status === 'success') return result
         }
     })
 }
 ​
 export default function fetchData(url: string) {
     promise = axios.get(url).then(res => res.data)
     return wrapPromise(promise)
 }

下面是使用该转换器的案例

这个是DogPic.tsx

 import React, {FC} from 'react'
 import fetchData from './fetchData'
 const data = fetchData('https://dog.ceo/api/breeds/image/random')
 const DogPic: FC = () => {
     const dogData = data.read()
     return(
     <image src={dogData.message}></image>
     )
 }
 export default DogPic

这个是App.tsx

 import {FC}, Suspense from 'react'
 import DogPic from './DogPic'
 ​
 const App:FC = () => {
     return (
     <Suspense fallback={<h2>fetching your dog</h2>}
     <DogPic/>
     </Suspense>
     
     )
 }

如果觉得有用可以去我的github仓库给个star哦

仓库指路 promise-support-suspense