评论

这个库能轻松解决99%的异步和逻辑加载时机问题(异步篇)

异步处理最佳实践

你是否纠结过底层业务逻辑(登陆、获取用户信息等)到底是放app.js的onLaunch还是page的onLoad里比较好,或者因为异步问题被迫放在了onload,我们来分析一下优劣

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  • 分析

onLaunch处理

优点:底层业务逻辑集中并且只需写一次,比较好维护

缺点:目前没有一个理想的方案来解决onLaunchonLoad的异步问题,包括注册回调重写onLoad请求拦截等。

onLoad处理

优点:因为不涉及跨页面通知,因此异步逻辑比较好处理

缺点:每个页面都得写一次底层业务逻辑,非常繁琐,而且既然是公用的底层业务逻辑,分散在每个页面的onLoad里,好像也不大对劲。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  • 抉择

按照高内聚低耦合的原则,那逻辑和数据放onLaunch里肯定的,不应该和普通page逻辑耦合在一起,通用的数据和逻辑应该在入口去处理,执行一次到处使用,就像vue的main.js一样,会注册一些技术层的基础设施(路由、状态管理等插件),那业务层的基础设施不就是token、用户信息、所在位置等逻辑吗?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  • 想象中的最佳实践

那我们的目标就是如何满足两者的优点,避免两者的缺点,做到真正的“高内聚低耦合”

1.保持底层业务逻辑写在入口app.js,避免耦合page里的逻辑

2.能在任何page里第一时间拿到globalData数据

3.使用方便,做到在业务开发中无感知,不需要写额外的调用、通知等代码

4.无任何副作用,不会影响其他功能,比如重写阻塞onLoad

5.灵活可配,适用以后此类任何业务

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  • 梦想成真

先看一段代码 ⬇️

// page.js
export default {
    name: 'Home',
    onLoadLogin(){
        //登录成功(拿到token) && 页面初始化完成
        //Tips:适用于某页面发送的请求依赖token的场景
    },
    onLoadUser(){
        //页面初始化完成 && 获取用户信息完成
        //Tips:适用于页面初始化时需要用到用户信息去做判断再走页面逻辑的场景
    },
    onReadyUser(){
        //dom渲染完成 && 获取用户信息完成
        //Tips:适用于首次进入页面需要在canvas上渲染头像的类似场景
    },
    onReadyShow(){
        //小程序内页面渲染完成 && 页面显示
        //Tips:适用于需要获取小程序组件或者dom,并且每次页面显示都会执行的场景
    },
}

应该懂什么意思了吧?是不是你理想中的样子,使用起来跟没有似的

⬆️ 这段示例代码满足了上面的第2、3、4条目标

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

再来看一段 ⬇️

// app.js
// 配置自定义钩子,所有钩子都可以随意组合搭配使用,执行机制类似于Promise.all(但不是用Promise实现的)
CustomHook.install({
 'Login':{
    // 自定义钩子名称、必须大写字母开头
    name:'Login',
    watchKey: 'token',
    onUpdate(token){
      //有token则触发此钩子
      return !!token;
    }
  },
 'User':{
    // 自定义钩子名称
    name:'User',
    watchKey: 'userInfo',
    onUpdate(user){
      //获取到userinfo里的userId则触发此钩子
      return !!user.userId;
    }
  }
  //依赖globalData中数据
}, globalData)

怎么样,是不是很棒,依赖globalData,名字可配,连触发规则都可配,而且还附加了可随意组合的功能(意外还解决了页面内逻辑执行时机问题,在下篇讲)

⬆️ 这段示例代码满足了上面的第1、5条目标。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -我是分割线 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

是不是跃跃欲试了,那就赶紧试试,好用回来告诉我! ⬇️(公司内部已接入两年了很稳定)

GitHub:https://github.com/1977474741/spa-custom-hooks


最后一次编辑于  2023-07-07  
点赞 7
收藏
评论

4 个评论

  • 黄兴
    黄兴
    2022-03-24

    高手

    2022-03-24
    赞同 1
    回复 1
    • Api调用师
      Api调用师
      2022-03-24
      哪里哪里~
      2022-03-24
      回复
  • 马尚尚
    马尚尚
    2022-03-22

    mark下,异步加载确实是日常开发中的一个痛点

    2022-03-22
    赞同 1
    回复 1
    • Api调用师
      Api调用师
      2022-03-22
      试试吧,用了你就回不去了,开发体验一级棒,真的。。。
      2022-03-22
      2
      回复
  • 那只是梦cium
    那只是梦cium
    2023-10-20

    打开某些页面的时候,我对用户信息要重新请求接口获取最新的,这个有没有钩子可以做

    2023-10-20
    赞同
    回复 5
    • Api调用师
      Api调用师
      2023-10-20
      具体什么需求,再具体点,拿到用户信息只是展示吗还是?
      2023-10-20
      回复
    • 那只是梦cium
      那只是梦cium
      2023-10-20回复Api调用师
      就是已经进入到小程序,用户信息UserInfo已经请求到,这样在每个页面onLoadUserInfo 是可以判断获取到了,但是这是刚进入到小程序获取到的,我有不少页面都需要实时更新,重新通请求口请求最新的用户信息,我现在是在需要的页面都加个方法重新请求,但是我想知道通过这个库有没有优雅点的写法
      2023-10-20
      回复
    • 那只是梦cium
      那只是梦cium
      2023-10-20回复Api调用师
      比如可以定一个onUpdateUserInfo的钩子,然后每次都重新刷新
      2023-10-20
      回复
    • Api调用师
      Api调用师
      2023-10-20回复那只是梦cium
      就是想重复触发onLoadUserInfo钩子是吗?
      2023-10-20
      回复
    • Api调用师
      Api调用师
      2023-10-20回复那只是梦cium
      “我现在是在需要的页面都加个方法重新请求”,你要知道钩子只是辅助通知的作用,不涉及其他逻辑,比如请求逻辑,所以你这个问题,跟钩子没有关系吧?除非涉及如何通知的问题。
      2023-10-20
      回复
  • 武曲心
    武曲心
    2022-03-22

    新建模板里官方就给出了异步处理的方法,在app.js里请求,page.js里拿数据,官方的方法基本上够用了

    2022-03-22
    赞同
    回复 6
    • Api调用师
      Api调用师
      2022-03-22
      哪个模板?我去瞅瞅好不好用
      2022-03-22
      回复
    • 武曲心
      武曲心
      2022-03-23回复Api调用师
      较新的开发工具看不到了,就是定义一个回调,很简单的方法,也足够处理大部分事件
      2022-03-23
      回复
    • 武曲心
      武曲心
      2022-03-23回复Api调用师
      大概就是这样,这方法用于tabBar页之间异步交互也是可以的
      2022-03-23
      回复
    • Api调用师
      Api调用师
      2022-03-23回复武曲心
      噢这就是我上面说的注册回调的方案,可以解决异步通知问题但比较麻烦也不灵活,每个页面都要在onLoad里去注册一个回调等待app.js执行,而且要处理“已经拿到了”和“正在拿的过程中“两种状态逻辑,并且每增加一个类似异步任务也都要写一套。你不妨试一下这个,开发体验差距很大的
      2022-03-23
      回复
    • 武曲心
      武曲心
      2022-03-23回复Api调用师
      官方这方法就是个回调,特点是够用,缺点也很明显,你这个主要是监听globalData的吧,要是在app.js里单纯的事件驱动page.js,又或者globalData里面多个属性变化完后再触发一个钩子,你这个能实现吗?(我没试过你的方法用了疑问句)。其实app.js和page.js交互还是其次,tabbar页之间的交互用得更多一些
      2022-03-23
      回复
    查看更多(1)
登录 后发表内容