【Wechat小程序支付•类别小说六】生命周期和路由,程序开垦生命周期

【微信小程序开发•系列文章六】生命周期和路由,程序开发生命周期

这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出。

  • 【微信小程序开发•系列文章一】入门
  • 【微信小程序开发•系列文章二】视图层
  • 【微信小程序开发•系列文章三】数据层
  • 【微信小程序开发•系列文章四】模块化
  • 【微信小程序开发•系列文章五】主界面
  • 【微信小程序开发•系列文章六】生命周期和路由

整个微信小程序从打开到关闭,整个过程可以分为很多阶段或者说状态,这一整段的过程,我们称之为小程序的生命周期。而周期中的每种不同的状态,到另一个状态的过度和转化,是需要一个触发机制的,这种机制我们称之为路由。

一、生命周期

图片 1

先来分析一下小程序官网给的这张图,它指的是Page的整个生命周期。要理解它,我们还是先回顾一下React.js的渲染机制。

react里面有一个virtual
DOM的概念,它实际上是把界面中的每个元素,用js实现的树形数据结构对应起来,结构里记录了节点的所有信息。我们可以把这个virtual
DOM看成一个独立的线程(js里没有真正的多线程),我们暂时称它为view线程,它的工作就是负责界面的渲染。当virtual
DOM上的数据发生变化的时候,界面的相应的部分就会跟着更新,更新机制被称为DOM
diff,这里有篇文章详细地分析了这种更新机制:

这里简单地介绍下:React.createClass创建的类都有一个render方法,它返回的不是真正的html代码,而是我们上面讲到的virtual
DOM,每一次渲染会直接按内部转换关系画到界面上,这个流程跟传统的网页渲染差不多。但是当要修改界面上某些元素的时候,react的性能才会真正的突显出来,它会去调用setState方法,这时有内置的算法会去比对这次操作引起的变化前后,最小的差异是什么,然后把这个最小的差异更新到界面上。DOM
diff的这篇文章讲到,传统的两个树形结构要分析出差异,复杂度至少要O(n^3),但react巧妙地把这个复杂度做到了接近O(n),优化了非常多,这也是它的核心算法。
这整个东东,就是我们上面讲到的“view线程”,它负责拿到数据后去做界面的更新,不过这个“线程”不处理主业务逻辑,只负责view层,用react的时候,它的内部框架已经帮我们做好了,所以react被称为是一个view层的框架。

那么我们还需要一个“线程”来处理主逻辑,这些就是我们自己要写的主要的代码。微信小程序跟react一样,也帮我们做好了这种渲染的算法。上图中,左侧绿色的部分,可以理解为上文中的“view线程”,应用启动时,他会用Page里的data初始值去Init出一个初始的virtual
DOM,当setData被调用的时候,MINA就会触发我们上面讨论的DOM
diff的过程,自动去更新界面。这也是为什么我们直接修改data无效的原因,一定要调用setData界面才会有变化。
上图右侧的“AppService线程”,其实就是我们说的主业务逻辑“线程”,我们就是跟它打交道。

下面简述一下整个生命周期的过程:
“view线程”和“AppService线程”在Page({…
})被执行时差不多同时启动(实际上,个人理解,后者应该要先一步启动,因为它要接收notify,纯属猜测)。前者init结束时,发送一个notify到后者。后者在create完成后,会同时触发Onload和Onshow回调(至于为什么要同时触发两个看起来差不多的状态,在下方会分析到),在这两个函数里面对page的data做一些修改(setData),然后挂起进入等待状态,等“view线程”init完,才会进行下面的流程,因为对用户来说这个应用的直接使用方式就是界面,背后逻辑用户不管,所以一定要等“view线程”准备好后,再做下面的事情才有意义。
如果Onload和Onshow有对data做修改,收到notify通知前也不会做什么动作,直到收到通知才会把变化发送给“view线程”,之后的流程里,setData就不用等通知了,因为这个通知只是为了让“AppService线程”知道“view线程”已经准备好了,进入可用状态了,后面就可以随意setData了,“view线程”随时都会做出响应,一发现数据变化就会重新render然后做DOM
diff操作,去更新界面。

而当用户进入另一个页面时(wx.nativateTo),onHide函数被触发,页面被切换到后台,可以看成是挂起状态,不会有什么动作。而当用户切换回来的时候(wx.navigateBack),onShow会被触发,但onLoad不会,onLoad只会在page初始化完成时触发一次,后面不会再进入了,所以对于只需要做一次的操作,千万不要写到onShow里面,如请求页面初始数据,要写到onLoad里。上面讲到“AppService线程”初始化的时候要同时触发onShow和onLoad,虽然字面上理解起来比较相似,但其实是不一样的过程,触发条件也是不一样的。

二、路由

图片 2

路由的控制逻辑主要在WAService.js里,这个文件,当程序在运行时,调试工具里可以查看。可惜的是,这个文件是压缩过的,格式化之后,还是很难看懂主要的逻辑。不过上表微信官方给的也表述得比较明显。

大概按这表介绍下路由的几种情况。
(1)当程序打开的时候,第一个页面会被加载(第一个页面,指在app.json里的pages配置的第一项),先初始化,这时这个页面的onLoad和onShow会被调用。
(2)从第一个页面跳到其它页面(navigateTo),这时第一个页面的onHide会被调用,跳过去的其它页面onLoad和onShow会被调用。
(3)如果是redirectTo跳转,则第一个页面被触发的是onUnload,其它跟(2)一样
(4)页面返回时,前一个页面被onUnload卸掉,返回后的页面onShow被调用。从这可以看出,返回时,前一个页面被销毁了。
(5)tab的切换,就只有onShow和onHide,当然第一个出现页面还有一个onLoad。
这几个情况也比较直观。

这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地…

  1. 初始化状态:此阶段仅启动服务线程所需的基本功能,比如信号发送模块。系统的初始化工作完毕,就调用自定义的onload和onshow,然后等待视图线程的“视图线程初始化完成”号。onload是只会首次渲染的时候执行一次,onshow是每次界面切换都会执行,简单理解,这就是唯一差别。
  2. 等待激活状态:接收到“视图线程初始化完成”信号后,将初始化数据发送给“视图线程”,等待视图线程完成初次渲染。
  3. 激活状态:收到视图线程发送来的“首次渲染完成”信号后,就进入激活状态既程序的正常运行状态,并调用自定义的onReady()函数。此状态下就可以通过
    this.setData 函数发送界面数据给界面线程进行局部渲染,更新页面。
  4. 后台运行状态:如果界面进入后台,服务线程就进入后台运行状态,从目前的官方解读来说,这个状态挺奇怪的,和激活状态是相同的,也可以通过setdata函数更新界面的。毕竟小程序的框架刚推出,应该后续会有很大不同吧。
  5. 结束状态:页面被回收或者销毁、应用被系统回收、销毁时触发。
App({ onLaunch: function() { // Do something initial when launch. }, onShow: function() { // Do something when show. }, onHide: function() { // Do something when hide. }, onError: function { console.log }, globalData: 'I am global data'})

示例代码:

图片 3页面的生命周期

  • 用户首次打开小程序,触发 onLaunch。
  • 小程序初始化完成后,触发onShow方法,监听小程序显示。
  • 小程序从前台进入后台,触发 onHide方法。
  • 小程序从后台进入前台显示,触发 onShow方法。
  • 小程序后台运行一定时间,或系统资源占用过高,会被销毁。

本篇文章介绍小程序的生命周期,由于小程序分为应用和页面两个部分,所以小程序的生命周期就涉及到三个部分,分别是:

// other.jsvar appInstance = getApp()console.log(appInstance.globalData) // I am global data
  1. 初始化状态:初始化视图线程所需要的工作,初始化完成后向
    “服务线程”发送初始化完成信号,然后进入等待状态,等待服务线程提供初始化数据
  2. 首次渲染状态:当收到服务线程提供的初始化数据后(json和js中的data数据),渲染小程序界面,渲染完毕后,发送“首次渲染完成信号”给服务线程,并将页面展示给用户。
  3. 持续渲染状态:此时界面线程继续一直等待“服务线程”通过this.setdata()函数发送来的界面数据,只要收到就重新局部渲染,也因此只要更新数据并发送信号,界面就自动更新。
  4. 结束状态:页面被回收或者销毁、应用被系统回收、销毁时触发。

App() 函数用来注册一个小程序。接受一个 object
参数,其指定小程序的生命周期函数等。

总结:

  • onLoad:
    页面加载。1)一个页面只会调用一次。2)参数可以获取wx.navigateTo和wx.redirectTo及<navigator/>中的
    query。
  • onShow: 页面显示1)每次打开页面都会调用一次。
  • onReady:
    页面初次渲染完成1)一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。2)对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。详见生命周期
  • onHide: 页面隐藏1)当navigateTo或底部tab切换时调用。
  • onUnload: 页面卸载1)当redirectTo或navigateBack的时候调用。
属性 类型 描述
data Object 页面的初始数据
onLoad Function 生命周期函数–监听页面加载
onReady Function 生命周期函数–监听页面初次渲染完成
onShow Function 生命周期函数–监听页面显示
onHide Function 生命周期函数–监听页面隐藏
onUnload Function 生命周期函数–监听页面卸载
  • 应用的生命周期
  • 页面的生命周期
  • 应用的生命周期对页面生命周期的影响

object参数说明:

由上图可知,小程序由两大线程组成:负责界面的视图线程(view
thread)和负责数据、服务处理的服务线程(appservice
thread),两者协同工作,完成小程序页面生命周期的调用。

视图线程有四大状态:

发表评论

电子邮件地址不会被公开。 必填项已用*标注