这两天写微信小程序注意到了有些时候会发现使用this.data.list
拿到的是空数据,但是明明自己已经请求到了数据了。这就很让人头疼。
原因:因为wx.request是一个异步的请求,所以数据请求的同时,可以继续向下执行函数。所以这里值还没有赋值上就开始打印了变量的值
比如:以下代码在执行的时候 this.updateData()
和 this.updateState()
不会分先后,可能先执行前者,可能先执行后者。如果先执行后者的话就先打印list
数组了,那么这个时候因为前者是请求数据的,还未执行呢就已经打印list
数组了,那么这个时候拿到的肯定是一个空数组。
Page({
data: {
list: []
},
onload: function() {
this.updateData();
this.updateState();
},
updateData: function() { //请求数据
var that = this
wx.request({
url: XXXXX, //你的请求地址
data: {},
success: function(res) {
that.setData({
list: this.data.data
}
}
})
},
updateState: function() {
var list = this.data.list
console.log(list)
//进行数据状态判断
},
})
这样运行的时候,还没有等到updateData更新到数据,已经在执行updateState了,这样得到的结果往往是不正确的,于是找方法发现了ES6 的promise
promise的用法为:
const promist = new Promise(function(resolve,reject){
if(/*异步操作成功*/){
resolve(value);
}else{
reject(error);
}
})
改造后代码:
Page({
data: {
list: []
},
onload: function() {
var that =this
new Promise(function(resolve,reject){
that.updateData(resolve);
}).then(function(){
that.updateState();
})
},
//请求数据
updateData: function(resolve) {
var that = this
wx.request({
url: XXXXX, //你的请求地址
data: {},
success: function(res) {
that.setData({
list: this.data.data
if(resolve!=null){
resolve('ok')
}
}
}
})
},
//拿数据打印
updateState: function() {
var list = this.data.data
console.log(list)
//进行数据状态判断
},
})
这样就能保证updateData执行完了之后才执行updateState
附
还有一个笨方法就是定时器了,先执行请求数据的代码updateData
,等过一会再执行打印数据的代码updateState
。
当然这种方法是不可取的,最好的办法就是用promise
来解决这种异步操作