使用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>
}

posted on 2020-11-28 11:01  nomanisaisland  阅读(452)  评论(0编辑  收藏  举报

导航