场景1:我们一个上传图片组件,点击上传的时候,需要一个弹窗提示。询问后在执行后面的上传逻辑
- 如上面的演示一样。但是我们要做的操作不一定是弹窗提示,还可能在其他节点执行逻辑其他的逻辑等。
- 大多做法可能是传入回调函数,或者把弹窗弹出逻辑提前。这样的代码就被写得很死,没有好的扩展性。
interface PropsType {
beforeUpload?: () => void
}
/**
* @description 上传图片
*/
const UploadImage = (props: PropsType) => {
const { beforeUpload } = props
const inputDom = useRef<HTMLInputElement>()
const upload = async () => {
// 上传之前的操作
(beforeUpload && await beforeUpload())
inputDom.current?.click()
}
return (
<>
<div className={styles.upload} onClick={upload}>
上传图片
</div>
<input type='file' ref={inputDom} style={{ width: 0 }} />
</>
)
}
export default UploadImage
- 上传 图片组件 是很单纯的功能,内部不会有业务方面的代码。
- 关键代码 await beforeUpload() ,beforeUpload 函数返回 resolve 状态的时候,才会向下执行上传
const beforeUpload = async () => {
await BaseModal.show({
content: '是否上传图片',
cancelText: '否',
confirmText: '是',
showCancel: true
})
}
return (
<div>
<UploadImage beforeUpload={beforeUpload} />
</div>
)
页面代码 BaseModal.show 返回的是个Promise , resolve 时,await beforeUpload() 就会响应到当前状态。
场景2:在小程序开发中我们要在页面返回的时候监听它返回,某些返回需要再次请求接口,有些返回则不用再次请求接口。
- 最直接的方法就是onShow 的时候执行逻辑操作,但是这样的冗余操作很多。
- 这里的返回监听不是使用 的 onShow 钩子,而是用的Promise 封装的路由。
- 第一个页面代码
export default () => {
const jumpPage = async () => {
await Router.navigateTo('/subpackage/landing-page/test2/index')
console.log('返回了');
}
return (
<View style={{ paddingTop: '200px' }}>
<BaseButton onClick={jumpPage}>跳转</BaseButton>
</View>
)
}
- 第二个页面
export default () => {
return (
<View>
<NavBar title="返回" />
<BaseButton onClick={() => Router.back()}>返回</BaseButton>
</View>
)
}
- 最重要的是 Router 类的核心逻辑
export class Router {
private static pagePromise = new Map()
private static setPromise(path: string) {
return new Promise((resolve, reject) => {
Router.pagePromise.set(path, { resolve, reject })
})
}
private static getPromise(path: string) {
return Router.pagePromise.get(path)
}
private static delPromise(path: string) {
return Router.pagePromise.delete(path)
}
static navigateTo(path) {
const currentPath = Taro.Current.router?.path || ""
Taro.navigateTo({ url: path })
return Router.setPromise(currentPath)
}
/**
* 返回
*/
static back(data, delta = 1) {
const pages = Taro.getCurrentPages()
// 目标页面的路径
const path = pages[pages.length - delta - 1]?.route || ""
const promise = Router.getPromise(path)
if (promise) {
promise.resolve(data)
Router.delPromise(path)
}
Taro.navigateBack({ delta })
}
}
- navigateTo 页面路由跳转的时候 ,生成 promise 的 一个map 数据,
- back 返回的时候,找到map 里面对应的路由,消费promise resolve()。以此来达到效果
总结:promise 基于事件循环的延迟 和 等待,还有很多妙用的地方。需要在具体工作中练习实践