国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - js教程 - 微信小程序組件生命周期的踩坑記錄

微信小程序組件生命周期的踩坑記錄

2022-01-25 16:23不曾 js教程

這篇文章主要給大家介紹了關于微信小程序組件生命周期的踩坑記錄,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

組件生命周期,通常是我們業務邏輯開始的地方。

如果業務場景比較復雜,組件生命周期有不符合預期的表現時,

可能會導致一些詭異的業務bug,它們極難復現和修復。

組件 attached 生命周期執行次數

按照通常的理解,除moved/show/hide等生命周期可能多次執行外,

嚴格意義上與組件加載相關的生命周期,如:created、attached、ready等,每個組件實例應該只執行一次。但是事實真的如此嗎?

背景

這個問題的發現,源于我們在小程序的報錯日志中,

收到大量類似Cannot redefine property: isComponent的報錯。

微信小程序組件生命周期的踩坑記錄

原因分析

通過變量名可以追溯到我們在代碼中的定義方式為:

Component({
 lifetimes: {
 attached() {
 Object.defineProperty(this, "isComponent", {
 enumerable: true,
 get() { return true },
 });
 },
 },
});

很容易理解,這種錯誤的起因在于試圖給對象重新定義一個不可配置的屬性,

具體可以查看MDN上的說明。

可是這個定義是寫在attached生命周期當中的,難道說,組件的attached生命周期被觸發了兩次?

天吶,這怎么可能?

是的,就是這么神奇!

場景還原

該問題并不容易復現,但是通過不斷刪繁就簡、抽絲剝繭,最終還是找到了問題的根源:

在頁面onLoad之前,通過setData改變狀態觸發子組件渲染,該子組件的attached生命周期會被觸發兩次。

微信小程序組件生命周期的踩坑記錄

可以通過以下代碼復現該場景,或者直接訪問小程序代碼片段。

頁面

// page.js
Page({
 data: {
 showChild2: false,
 },
 onChild1Attached() {
 this.setData({ showChild2: true });
 },
});

<!-- page.wxml -->
<child1 bind:attached="onChild1Attached"></child1>
<child2 wx:if="{{ showChild2 }}"></child2>

子組件1

與頁面一同渲染,并在attached的時候,通過triggerEvent,通知頁面更新狀態并渲染子組件2。

// child1.js
Component({
 lifetimes: {
 attached() {
 this.triggerEvent("attached");
 },
 },
});

<!-- child1.wxml -->
<view>child1</view>

子組件2

執行了兩次attached生命周期,導致報錯。

// child2.js
Component({
 lifetimes: {
 attached() {
 Object.defineProperty(this, "isComponent", {
 enumerable: true,
 get() { return true },
 });
 },
 },
});
<!-- child2.wxml -->
<view>child2</view>

組件 ready 生命周期的執行時機

小程序官方文檔沒有明確給出組件生命周期的執行順序,不過通過打印日志我們可以很容易地發現:

  • 在加載階段,會依次執行:created -> attached -> ready
  • 在卸載階段,會依次執行:detached

所以,看起來這個順序貌似應該是:created -> attached -> ready -> detached。

但是實際情況果真如此嗎?

背景

有段時間,客服經常反饋,我們的小程序存在串數據的現象。

例如:A商家的直播展示了B商家的商品。

原因分析

串數據發生在多個場景,考慮到數據是通過消息推送到小程序端上的,最終懷疑問題出在WebSocket通信上。

在小程序端,我們封裝了一個WebSocket通信組件,核心邏輯如下:

// socket.js
Component({
 lifetimes: {
 ready() {
 this.getSocketConfig().then(config => {
 this.ws = wx.connectSocket(config);
 this.ws.onMessage(msg => {
 const data = JSON.parse(msg.data);
 this.onReceiveMessage(data);
 });
 });
 },
 detached() {
 this.ws && this.ws.close({});
 },
 },
 methods: {
 getSocketConfig() {
 // 從服務器請求 socket 連接配置
 return new Promise(() => {});
 },
 onReceiveMessage(data) {
 event.emit("message", data);
 },
 },
});

簡單說,就是在組件ready時,初始化一個WebSocket連接并監聽消息推送,然后在detached階段關閉連接。

看起來并沒有什么問題,那么就只能從結果倒推可能不符合常理的情況了。

數據串了 -> WebSocket 消息串了 -> WebSocket 沒有正常關閉 -> close有問題/detached未執行/ready在detached之后執行

場景還原

此處的實際業務邏輯較為復雜,因此只能通過簡化的代碼來驗證。

通過不斷試驗,最終發現:

組件的 ready 與 detached 執行順序并沒有明確的先后關系。

微信小程序組件生命周期的踩坑記錄

可以通過以下代碼復現該場景,或者直接訪問小程序代碼片段

頁面

// page.js
Page({
 data: {
 showChild: true,
 },
 onLoad() {
 this.setData({ showChild: false });
 },
});

<!-- page.wxml -->
<child wx:if="{{ showChild }}" />

組件

組件未ready的時候銷毀組件,會先同步執行detached,然后異步執行ready。

// child.js
Component({
 lifetimes: {
 created() {
 console.log("created");
 },
 attached() {
 console.log("attached");
 },
 ready() {
 console.log("ready");
 },
 detached() {
 console.log("detached");
 }
 },
});

拓展

即便是將初始化的工作從ready前置到attached階段,只要有異步操作,仍然可能存在detached先于異步回調執行的情況。

因此,請不要完全信任在組件detached階段的銷毀操作。

總結

到此這篇關于微信小程序組件生命周期踩坑的文章就介紹到這了,更多相關小程序組件生命周期內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://juejin.cn/post/6934971793262247944

延伸 · 閱讀

精彩推薦
  • js教程Javascript中的奇葩知識,你知道嗎?

    Javascript中的奇葩知識,你知道嗎?

    這篇文章主要介紹了一些Javascript中的奇葩知識,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下...

    原罪7802022-01-06
  • js教程五種使 JavaScript 代碼庫更干凈的方法

    五種使 JavaScript 代碼庫更干凈的方法

    今天向大家介紹5種使JavaScript代碼庫更干凈的方法,一起來看一下都有哪些吧!...

    Mason程10662021-12-29
  • js教程你不知道的 JS 沙箱隔離

    你不知道的 JS 沙箱隔離

    本文接下來的內容,將介紹我在探索基于 Web Worker 實現 JavaScript 沙箱隔離方案過程中的一些資料收集、理解以及我的踩坑和思考的過程。...

    前端大全10342021-12-29
  • js教程JS中多層次排序算法的實現代碼

    JS中多層次排序算法的實現代碼

    這篇文章主要給大家介紹了關于JS中多層次排序算法的實現代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需...

    桂花載酒少年游8192021-12-27
  • js教程原生js中運算符及流程控制示例詳解

    原生js中運算符及流程控制示例詳解

    這篇文章主要給大家介紹了關于原生js中運算符及流程控制的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價...

    meichaoWen5132021-12-27
  • js教程JavaScript 獲取滾動條位置并將頁面滑動到錨點

    JavaScript 獲取滾動條位置并將頁面滑動到錨點

    這篇文章主要介紹了JavaScript 獲取滾動條位置并將頁面滑動到錨點的的相關資料,幫助大家更好的理解和學習使用JavaScript,感興趣的朋友可以了解下...

    丶Serendipity丶9792022-01-20
  • js教程JS實現公告上線滾動效果

    JS實現公告上線滾動效果

    這篇文章主要為大家詳細介紹了JS實現公告上線滾動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Jeslie-He4132021-12-29
  • js教程微信小程序實現簡單購物車功能

    微信小程序實現簡單購物車功能

    這篇文章主要為大家詳細介紹了微信小程序實現簡單購物車功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    mossbaoo5222021-12-22
主站蜘蛛池模板: 密臀av | jizz中国zz女人18高潮 | 精品少妇一区二区三区日产乱码 | 亚洲激情在线 | 蜜桃精品在线观看 | 欧美激情视频一区二区三区在线播放 | 久久99精品久久久 | 性色浪潮 | 免费观看视频毛片 | 午夜视频免费在线观看 | 蜜桃免费视频 | 午夜www| 91在线中文 | 国产精品美女视频 | 国产成人毛片 | 久久精品高清 | 群p在线观看 | 九九国产精品视频 | 综合99 | 一级黄片毛片免费看 | 久久久国产一级 | 国产一区二区免费 | 午夜精品久久久久久久久久久久 | 四影虎影ww4hu55.com | 午夜激情视频网站 | 欧美激情在线精品一区二区三区 | 一区二区三区在线观看国产 | 亚洲欧洲成人 | 97久久久 | 黄色天堂 | 国产一区二区视频在线观看 | 91国产精品| 五月婷婷香蕉 | av一区二区在线观看 | 国产精品欧美一区二区 | 日韩一区二区三区在线观看 | 精品一区二区在线观看 | 国产福利电影在线观看 | 四虎影视在线播放 | 欧美在线影院 | 国产精品久久99 |