问题产生:
准备使用微信小程序去获取openid,把获取openid的代码写在app.js的onlaunch中。想在后续的页面中使用openid,结果在页面中打印出来显示是和预期的不太一样:
// APP.JS
var ApiList = require('utils/api.js');
App({
onLaunch: function () {
// // 展示本地存储能力
// var logs = wx.getStorageSync('logs') || []
// logs.unshift(Date.now())
// wx.setStorageSync('logs', logs)
var login_url = ApiList.ApiList.login;
var _this=this;
console.log( "Launch" );
// 登录
wx.login({
success: res => {
// console.log( res );
// 发送 res.code 到后台换取 openId, sessionKey, unionId
// 去后端获取openid
wx.request({
url: login_url,
data:'code='+res.code,
method:'post',
header:{
"content-type":"application/x-www-form-urlencoded"
},
success:function( login_data ){
// console.log( login_data );
if( login_data.data.status == 200 ){
_this.globalData.openid = login_data.data.data.openid;
_this.globalData.sessionkey = login_data.data.data.session_key;
console.log('Wx.request');
console.log(_this.globalData);
}else{
wx.showModal({
title: '提示信息',
content: '获取OpenId失败,请重试',
})
}
}
})
}
})
globalData: {
userInfo: null,
openid:null,
sessionkey:null
}
})
//Index.js
Page({
data: {
},
onLoad: function (options) {
console.log('Index OnLoad ');
console.log(getApp().globalData);
},
})
按照正常的逻辑,Index.js中的打印会正常显示出openid和sessionkey参数。
结果打印出来的结果是:
Launch
Index OnLoad
{userInfo: null, openid: null, sessionkey: null}
{userInfo: null, openid: "oQ8lB1ZfKddcDJnyKw_tEu2MeIrw", sessionkey: "ehUFQUc1aZqCqMFp8n/F3Q=="} ·
显示的结果和预期的不太一样,查了下资料,是因为js是异步执行,也就是说在发送ajax请求的时候,后续的代码继续执行了。
问题如何解决:
在Js中可以使用Promise保证代码的执行顺序,具体的语法:
// 定义一个方法,接受一个毫秒的时间戳参数
var func = function( time ){
// 实例化一个promise ( resolve 解决 reject 拒绝 )
return new Promise( function( resolve , reject ){
// 打印一个日志
console.log('Function Call');
// 模拟一个Ajax请求
setTimeout(function () {
// 在这里模拟接口调用 小于3秒钟,代表执行成
if( time < 3000 ) {
//这里告诉Promise 成功了,然后去执行then方法的第一个函数
console.log(time+'s,success');
resolve('success');
}else{
console.log(time+'s,fail');
//这里告诉Promise 失败了,执行的是then方法的第二个函数
reject('fail');
}
}, time);
});
}
// 调用func方法,1s执行成功, 成功之后走 第一个then的function
// 在成功的回调方法中,在调用func,4s中执行失败,返回失败,走第二个then
// 第二个function
func(1000).then(function( data ){
console.log(data);
return func(4000);
}).then(function(data){
console.log(2000);
},function(){
console.log( 'fail' );
})
修改以上的代码为:
APP.JS
//app.js
var ApiList = require('utils/api.js');
App({
onLaunch: function () {
console.log( "Launch" );
},
globalData: {
userInfo: null,
openid:null,
sessionkey:null
},
wechatLogin:function(){
var login_url = ApiList.ApiList.login;
var _this = this;
return new Promise( function( resolve , reject ){
wx.login({
success: res => {
// console.log( res );
// 去后端获取openid
wx.request({
url: login_url,
data: 'code=' + res.code,
method: 'post',
header: {
"content-type": "application/x-www-form-urlencoded"
},
success: function (login_data) {
if (login_data.data.status == 200) {
_this.globalData.openid = login_data.data.data.openid;
_this.globalData.sessionkey = login_data.data.data.session_key;
console.log('Wx.request');
console.log(_this.globalData);
resolve('success');
} else {
reject('获取OpenId失败');
}
}
})
}
})
});
},
noAuthPower:function(){
wx.showModal({
title: '授权提醒',
content: '未授权将无法使用小程序,请授权获取你的基本信息',
cancelText:'取消',
confirmText:"去授权"
});
}
})
Index.js
// pages/user/index.js
var app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
},
onLoad: function (options) {
var that = this;
app.wechatLogin().then(function(){
that.getWechatUserInfo();
}).then( function(){
console.log('OnLoad ');
console.log(getApp().globalData);
});
},
getWechatUserInfo:function () {
console.log('getWechatUserInfo');
var that = this;
return new Promise(function (resolve, reject) {
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
getApp().globalData.userInfo = res.userInfo;
console.log(res.userInfo);
resolve('success');
}
})
} else {
// 没有授权请求获取用户的授权信息
reject(getApp().noAuthPower());
}
}
})
});
}
})