这两天写微信小程序注意到了有些时候会发现使用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
来解决这种异步操作