在微信小程序的开发过程中我们都见过这样一段代码
app.js
index.js
这是我们开发一个项目时微信的开发工具自动帮我们生成的部分代码,当时我就对这段代码中他说的加入callback防止网络请请求在Page.onload之后返回就很疑惑:
1、为什么网络请求会在page.onload之后返回,这种情况如果发生了会造成什么样的结果?
2、app.js中的userInfoReadyCallback方法是什么鬼,时微信提供的吗,app.js中的这个方法是固定的吗?
在很长的一段时间里我都是带着这个疑惑去做项目的,但直到有一天我在另一个地方遇到了一个差不多的问题我才明白了这callback的所有问题。先描述一下我的问题首先我从user数据库中的取出一个user对象,这个user对象中有一个数组字段chatroom记录的是用户加入的所有的群聊的id。当取出user对象后需要把chatroom中的每一个id对应的chatroom的对象也去出来最后一起放到Page.data中。这个时候问题就出现了当我向data中放完chatroom后却显示data中的chatroom仍然是空的。直接看我的问题代码吧:
Page({
/**
* 页面的初始数据
*/
data: {
//用户信息
user: {
userInfo: {},
name: "暂无信息",
phone: "暂无信息",
address: ["暂无信息","暂无信息","暂无信息"],
bookchatroom: []
},
//控制信息
hasUserInfo: false,
canIUse: wx.canIUse("button.open-type.getUserInfo")
},
/**
* 调用云函数获取用户的相关信息
* 然后利用获取到的信息设置本页面的data.user的数据
*/
setUser: function (userInfo) {
var self = this
wx.cloud.callFunction({
name: "login",
//向云函数传递的各种参数,系统会在我们传递的参数的基础上自动加上appid以及openid两个参数
//我们此处查询用的是openid,不需要额外传参
data: {},
success: function (res) {
var user = res.result.data[0]
//再次调用云函数获取用户加入的聊天室的相关信息
var bookchatroom = []
for ( var i = 0; i <= user.bookchatroom.length; i ++ ) { //一个一个的获取chatroom,我当时就是这么写的,虽然现在看起来很蠢,但是幸亏我当时这么写了,要不我也不会深刻的体会到现在我们所讨论的问题
wx.cloud.callFunction ({
name: "getchatroom",
data:{
id: user.bookchatroom[i]
},
success: function (res) {
bookchatroom.push(res.result.data[0])
}
})
}
//把我们从数据库中获取的user以及该用户加入的所有聊天室的信息一起放的page.data中
self.setData({
user: {
userInfo: userInfo,
name: user.name,
phone: user.phone,
address: user.address,
bookchatroom: bookchatroom
}
})
//按照常理来说程序顺序执行到此处page.data中的信息应该已经全部放好了,那我们不妨输出一下看看
console.log(self.data)
//打印完我们会发现page.data.user.bookchatroom的值是null,也就是说此时从数据库中获取的bookchatroom的值并没有成功的注入
}
})
},
为什么会出现上边的情况呢?多番思考后突然想的了开头使用callback时官方的解释“// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况”,这时我们就不难理解这句话了。结合此处我们遇到的问题来看的话是这样的,在微信小程序中,网络请求和本地代码的执行是异步的,当我们发送了网络请求之后本地并不会等待返回的结果,而是跳过去继续执行后面的代码,也就是说在我们从数据库中请求的bookchatroom返回之前"self.setData({…})"这段代码就已经执行完了。所以最后打印出来的page.data.user.bookchatroom的内容为null。
既然已经知道了问题所在我们怎么解决呢?这个时候请再看官方给的app.js、index.js中的callback代码应该就会发现解决方法了,就不用再细说了(其实是打了这么多字不想打了,有需要的的话再细说吧)
当然除了借鉴官方的那个解决方法还有个更舒服、更简单的方法,但是个人认为官方的callback解决办法更加精妙,更加…总之妙不可言