小程序setData函數小探究

官方文檔可以知道

這裏寫圖片描述

setData函數改變Page的data是同步的,會異步通知視圖層data的改變,視圖層收到通知後進行渲染。即官方文檔裏生命週期的Send Data箭頭

callback分析

先上代碼:

Page({
  data: {
    theData: 1
  },
  onLoad: function(options) {
    console.log("data begin:" + this.data.theData);
    this.setData({
      theData: 2
    }, () => {
      console.log("callback");
    });
    console.log("data after:" + this.data.theData);
    /*長耗時*/
    for (var i = 0; i < 1000000; i++) {
      for (var j = 0; j < 2000; j++) {
        j++;
      }
    }
    console.log("data long after:" + this.data.theData);
  }
})

結果:
這裏寫圖片描述
結果描述:data begin:1與data after:2瞬間就打印,並且頁面也瞬間顯示完成,隨後過幾秒後data long after纔打印,並且緊接着callback也打印了。

結論
1、邏輯層是單線程,視圖層的回調callback是異步代碼段,因此邏輯層的高耗時代碼段執行完成後,異步代碼段纔會執行。(其實就是js引擎就是單線程,沒啥好結論的[捂臉][捂臉])
2、setData函數是同步方法,使用serData後,data對象的值就是修改後的,後面的代碼取出的data就是修改後的,可以放心處理不必擔心出現異步問題。

callback再分析:

setData後,邏輯層會通知視圖層data改變了,隨後視圖層會進行渲染。
在這裏插入圖片描述

渲染是需要耗時的,這裏猜測一下:callback是在邏輯層通知視圖層成功後就立即調用,還是在視圖層渲染成功後才通知邏輯層調用callback?(即是在1處執行callback還是在2處執行callback?)

先上代碼:

Page({
  data: {
    colorMap: [],
    count: 0
  },
  onLoad: function() {},
  change: function() {
    var columnAmount = 75;
    var rowAmount = 200;
    var colorMap = [];
    //這裏隨機生成1~5數字,用於前端隨機展示5種不同的顏色塊,顏色塊共200*75個
    //所以視圖層渲染起來會比較慢
    for (var i = 0; i < rowAmount; i++) {
      colorMap[i] = [];
      for (var j = 0; j < columnAmount; j++) {
        colorMap[i][j] = Math.ceil(Math.random() * 5);
      }
    }
    var that = this;
    console.log("begin setData")
    this.setData({
      //注意該setData會導致視圖層較高耗時
      colorMap: colorMap
    }, () => {
      that.data.count++;
      console.log("callback", that.data.count)
      if (that.data.count < 5) {
        that.change();
      }
    });
  }
});
<view class='mycontainer'>
  <view wx:for="{{colorMap}}" class="row" wx:for-item="rowitem">
    <view wx:for="{{rowitem}}" class='box color{{boxitem}}' wx:for-item="boxitem"></view>
  </view>
  <button bindtap="change">change</button>
</view>
.mycontainer{
  width: 100%;
  height: 100%;
}
.box{
  width: 10rpx;
  height: 10rpx;
  float: left;
}
.row{
  width: 100%;
  height: 10rpx;
}
.color1{background-color: red;}
.color2{background-color: yellow;}
.color3{background-color: rgb(47, 179, 255);}
.color4{background-color: cyan}
.color5{background-color: orange;}

結果:
在這裏插入圖片描述

結果描述:
點擊change後:
1、迅速打印出begin setData
2、然後等了大約半秒
3、模擬器出現隨機顏色塊,同時控制檯打印出callback
4、重複了1~3一共5次

代碼可以看出,主要的耗時是在視圖層的渲染裏的,如果是邏輯層通知視圖層成功後就執行callback,那麼應該是先打印callback,然後大約半秒,模擬器纔出現隨機顏色塊。因此得出下面結論:

結論:
邏輯層執行setData後,視圖層進行渲染,渲染成功後,邏輯層的callback纔會被調用。

小結:因此對於要求必須渲染成功後才允許執行某代碼塊的場景,可以放心使用setData的callback方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章