评论

零成本解决onLaunch与onLoad异步问题(全网独家方案)

小程序onLaunch与onLoad异步问题解决方案

前言

  1. onLaunchonLoad的异步问题,onLaunch里的请求数据还没拿到,onLoad中就执行了。
  2. 热启动小程序时 onLaunch不执行,app没有提供针对于页面的全局前置处理钩子。

其实也不止是onLaunchonLoad这两个钩子异步导致的顺序问题,当页面使用的自定义组件内部也在其生命周期中进行了一些请求,那么就不止是页面onLoad钩子执行顺序的问题了,而涉及到了 app页面组件三方的生命周期执行顺序问题。

这些典型的问题一直是很多小程序开发者的困扰,网上很多解决方案都需要针对一个个页面进行大量的改动,总是差点意思。

而现在,我彻底的解决了这些问题,并且改动极少,只需在 app里添加几行代码即可,其它页面无需任何改动,真正做到零成本解决问题,我把这些解决方案写成了一个js库,它叫wxbuf

github仓库,欢迎star: https://github.com/laivv/wxbuf

现在,我们使用wxbuf来解决上面两个典型的问题,以下假定你已经在项目中导入了wxbuf

onLaunch与onLoad的异步问题

wxbuf支持apponLaunch钩子返回promise来推迟整个app、页面、组件的所有生命周期执行。

也就是说,所有的生命周期都要等到onLaunch执行完毕并且是Fulfilled(已成功)状态才会执行,我们把这个功能叫异步onLaunch

异步onLaunch默认关闭, 需要在app.js中配置开启后方可使用

示例:

// app.js
// 导入wxbuf
import wxbuf from 'wxbuf'

// 配置wxbuf
wxbuf.config({
  asyncOnLaunch: true  // 开启异步onLaunch支持
})

App({ 
  async onLaunch() {
    // 请确保返回的`promise`最终会是`Fulfilled(已成功)`状态,否则整个app将永远不会被加载  
    try {
      const res = await fetch('/api/user')
      //...
    }catch(e) {}
  }
})

由此,整个app、页面及组件的生命周期都将在onLaunch执行完毕并且是Fulfilled(已成功)状态时才会继行续执行,确保了页面onLoad或组件createdattached等生命周期中一定能获取到正确的数据。

onLoad的问题

由于onLaunch只在冷启动阶段执行,通过热启动小程序进入指定页面的时候不再执行,因此需要一个全局并针对于页面统一处理的前置处理钩子,类似于上面的异步onLaunch那样。

wxbuf支持在app中配置onPageInit钩子,通过它返回promise来推迟页面和面页上的组件所有生命周期执行。

也就是说,所有的页面及其组件的生命周期都要等到onPageInit执行完毕并且是Fulfilled(已成功)状态才会执行。

wxbuf还支持在页面配置onInit钩子,和上述onPageInit功能一样,区别是onInit是写在页面上的,也只作用于当前页面。

以上两个钩子默认关闭, 需要在app.js中配置开启,开启后方可在app中使用onPageInit、页面中使用onInit

示例:

// app.js
// 导入wxbuf
import wxbuf from 'wxbuf'

// 配置wxbuf
wxbuf.config({
  pageOnInit: true  // 开启pageOnInit
})

App({ 
  onPageInit(page, options) {
    // 请确保返回的`promise`最终会是`Fulfilled(已成功)`状态,否则所有页面和组件将永远不会被加载  
    return new Promise((resolve) => setTimeout(() => resolve(), 1000))
  }
})
// page代码
Page({
  onInit(options) {
    // 请确保返回的`promise`最终会是`Fulfilled(已成功)`状态,否则当前页面及其组件将永远不会被加载  
    return new Promise((resolve) => setTimeout(() => resolve(), 1000))
  },
})

执行顺序

总结一下执行顺序:

app.onLaunch -> app.其它钩子

app.onLaunch -> app.onPageInit(如果有) -> page.onInit(如果有) -> page.其它钩子

app.onLaunch -> app.onPageInit(如果有) -> page.onInit(如果有) -> component.其它钩子

以上所有后面的钩子都将依次等待它前面的钩子执行完毕并且是Fulfilled(已成功)状态才会执行,因此建议加上错误处理防止后续生命周期被锁死

点赞 1
收藏
评论
登录 后发表内容