使用promise实现跳转页面返回后执行后续代码
最近遇到一个业务场景,需要跳转到下个页面,等用户操作完后,返回当前页面,当前页面的数据可以同步更新用户的操作数据。使用promise对象可以做到这点,promise对象内部保存着一个未来才会结束的事件,并且promise对象的状态只有异步才会触发状态改变(状态改变后无法更改)。刚开始直接在跳转事件内部注册onshow事件,但是出现一个bug,onshow事件只会执行一次,后续就无法再触发手动注册的事件了,可能是淘宝小程序内部实现问题,微信小程序暂时未做测试。后续直接注册一个空的onshow生命周期,在onshow生命周期内部调用需要触发的事件,在需要触发的事件触发后代码才会执行到下一步(代码必须要是同步的,才可以实现这个功能)。
// 初步实现代码(小程序版)
async func () {
// 跳转代码
const onShowPromise = new Promise((resolve) => {
this.onShow = () => {
this.onShow = () => { }; // 将onShow初始化
resolve();
};
});
await onShowPromise
// 需要更新的代码
}
// 完善版
onShow1(){}, // 防止为空
onShow(){
onShow1()
}
async func () {
// 跳转代码
await new Promise((resolve) => {
this.onShow1 = () => {
this.onShow1 = () => { }; // 将onShow初始化
resolve();
};
});
// 需要更新的代码
}
封装一下
// utils.js
class AwaitWhileComeBack {
page = null
constructor() {}
register(page) {
this.page = page
page.awaitShow = () => {}
}
lister() {
this.page.awaitShow()
}
async awaitFunc(fn) {
await new Promise((resolve, reject) => {
this.page.awaitShow = () => {
this.page.awaitShow = () => {}
resolve(true)
}
})
fn()
}
static instance = new AwaitWhileComeBack()
}
module.exports = {
awaitWhileComeBack: AwaitWhileComeBack.instance
}
// page.js
const {
awaitWhileComeBack
} = require("../../utils/util")
awaitWhileComeBack.register(Page)
Page({
onShow() {
awaitWhileComeBack.lister()
},
navigatoToSomeWhere() {
wx.navigateTo({
url: '../next/next',
})
awaitWhileComeBack.awaitFunc(()=> {
console.log(11111111)
})
},
})
// react版
import { useEffect, useState } from 'react'
export type UseEventListenerOptions = {
target?: Window | Document
capture?: boolean
passive?: boolean
depends?: unknown[]
}
export const inBrowser = typeof window !== 'undefined'
// 参考的是react-vant的自定义hooks源码,自己删减了部分
export const useEventListener = (type: string, listener: EventListener, options: UseEventListenerOptions = {}): void => {
const { target = window, depends = [] } = options
let attached: boolean
const add = () => {
const element = target
if (element && !attached) {
element.addEventListener(type, listener)
attached = true
}
}
const remove = () => {
const element = target
if (element && attached) {
element.removeEventListener(type, listener)
attached = false
}
}
useEffect(() => {
add()
return () => remove()
}, [target, ...depends])
}
type VisibilityState = 'hidden' | 'visible'
export const usePageVisibility = () => {
const [visibility, _setVisibility] = useState<VisibilityState>('visible')
const setVisibility = () => {
if (inBrowser) {
_setVisibility(document.hidden ? 'hidden' : 'visible')
}
}
useEffect(() => {
setVisibility()
}, [])
useEventListener('visibilitychange', setVisibility, { depends: [visibility] })
return visibility
}
let onShow = () => {}
const useListen = () => {
const pageVisibility = usePageVisibility()
useEffect(() => {
onShow()
}, [pageVisibility])
}
const awaitFunc = async () => {
return await new Promise((resolve) => {
onShow = () => {
onShow = () => {}
resolve(true)
}
})
}
export const awaitWhileComeBack = {
useListen,
awaitFunc
}
// 用法
import {awaitWhileComeBack } from 'utils'
export const Page = () => {
awaitWhileComeBack.useListen()
return <div onClick={async()=>{
await awaitWhileComeBack.awaitFunc()
// 返回后需要执行的逻辑
}}><div>
}
NO MAN IS A ISLAND
posted on 2020-11-28 11:01 nomanisaisland 阅读(468) 评论(0) 编辑 收藏 举报