评论

看看这篇你就知道,如何使用Promise控制隐私弹窗

你是怎么控制协议弹窗的?看看这篇文章可能会有新发现哦

Hi guys, 本期介绍的内容是全局通信弹窗的方案

背景介绍

本项目,为论坛型小程序,由于背景原因,使用技术栈较为老旧。
具备用户隐私弹窗黑名单用户弹窗权限弹窗等全局性提示。

  • 用户隐私弹窗:
    • 程序启动时展示,在所有用户动作前触发
  • 黑名单用户弹窗:
    • 黑名单用户涉及业务操作时触发
  • 权限弹窗:
    • 非会员用户访问会员内容时触发

问题描述

在隐私协议这一环节中:

  • 弹窗为自定义组件,挂载于tabbar页面上;
  • 最新用户隐私协议内容获取(需访问Https请求)/是否签约,在App.vue的onLaunch中;

会小概率出现隐私协议未弹起的情况。为什么不使用其他的生命周期因为要更早的拿到数据。

问题原因

App.vue中调用接口获取隐私协议大约200ms,首页弹窗组件挂载至节点时间可能会>200ms。这里补充一张uni-app的生命周期图。

由此可见App.vue的生命周期是早于组件挂载的,但是问题点在于没法确定组件挂载的具体完成时间。

解决步骤

连续监听节点是否已存在,使用uni.createSelectorQuery。这明显是一个笨(dumber)方法,耗费性能的同时让代码变得无缘无故,显然💩山就是这么来的。但是App.vue没有钩子函数可以直接在组件挂载后调用。
等等!!!钩子函数?! 冷静一下(calm down)既然没有钩子函数那就自己创造一个呗

利用Promise对象的async await语法糖,结合小程本身的全局对象getApp().globalData,我们做了个简易的钩子函数(甚至可能不算是个钩子函数)。

  1. 我们先创建一个对象Confirm
  2. Confirmconstructor中声明resolverejectpromise
  3. 将其挂载于getApp().globalData
  4. 当组件的生命周期执行到mounted
  5. App.vue中获取最新协议的方法await这个Promise
  6. resolve后触发弹窗

思路介绍清楚了,我们来看下demo代码。

// service.js
export class Confirm {  
  constructor() {  
    this.resolve = () => {  
      //  do something
    };  
    this.reject = () => {  
      //  do something
    };  
    this.promise = new Promise((resolve, reject) => {  
      this.resolve = resolve;  
      this.reject = reject;  
    });  
  }  
}
// App.vue
import { Confirm } form '../utils/service.js';
globalData: {  
    appConfirmnew Confirm(),
},
//  tipsWindows.vue
mounted() {
    getApp().globalData.appConfirm.resolve();  
},
//  tipsWindows.vue
async alertPolicy() {
    await getApp().globalData.appConfirm.promise;  
    // do something
}

最后

In the end,这个问题肯定有更好的解决方案,但这是目前我所能想到比较好的方案了。在使用这个方案的时候,发现结合上Proxy的话可以延展出更多的玩法,比如Proxy弹窗的open方法,在每次弹出前判断是否为重复提示等等。

最后一次编辑于  08-20  
点赞 1
收藏
评论
登录 后发表内容