官方文档可以知道
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方法。