問題概述
基于小程序request請求是異步的特性檐春,app.js onLaunch()
中的請求與index.js onLoad()
中的請求是同時進行的,導致onLoad()
中如果有基于onLaunch()
返回的數據的請求苗膝,會有報錯,這樣會使onLoad()
中request請求的數據“第一次”無法正常獲取。
我的小程序中所有的requset請求都需要在header中帶著用戶唯一的token進行發(fā)起,而token是在app.js onLaunch()
中的wx.login()返回中獲取到的(由code到后臺換日),之后通過wx.setStorageSync('token', res.data)
存到小程序中兼砖。要解決問題奸远,就需要解決request請求異步的問題,而且是在兩個js文件之間掖鱼。
使用Promise()
稍微說一下promise
var promise = new Promise(function(resolve, reject) {
if (/* 異步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(value) {
// failure
});
Promise 構造函數接受一個函數作為參數然走,該函數的兩個參數分別是 resolve 方法和 reject 方法援制。
- 如果異步操作成功戏挡,則用 resolve 方法將 Promise 對象的狀態(tài),從「未完成」變?yōu)椤赋晒Α梗磸?pending 變?yōu)?resolved)晨仑;
- 如果異步操作失敗褐墅,則用 reject 方法將 Promise 對象的狀態(tài),從「未完成」變?yōu)椤甘 梗磸?pending 變?yōu)?rejected)洪己。
接下來在小程序中引入promise庫妥凳。到bluebird官網中下載壓縮版本的promise庫。直接打開bluebird.core.min.js
答捕,復制代碼逝钥。
Bluebird is a fully featured JavaScript promises library with unmatched performance.
小程序內新建一個promise.js文件,將bluebird.core.min.js
中的代碼復制進去拱镐。
在app.js
中通過require
引入:
<!-- app.js -->
const Promise = require('units/promise.js');
這樣就可以在小程序內使用promise了艘款,該庫大小大概在64kb左右持际,可以接受。
接下來直接貼代碼:
<!-- app.js -->
App({
onLaunch: function(){
<!-- 調整代碼結構哗咆,原本在此進行的wx.login操作放到下面去 -->
...
},
//登錄蜘欲,獲取token
getToken: function(){
let _this = this;
return new Promise(function(resolve, reject){
wx.checkSession({
success: function (res) { resolve(res); },
fail: function (res) {
wx.login({
success: res => {
// 發(fā)送 res.code 到后臺換取 openId, sessionKey, unionId
if (res.code) {
wx.request({
url: CONFIG.loginUrl,
data: {
code: res.code
},
header: {
'shopId': CONFIG.shopId
},
method: 'POST',
success: res => {
wx.setStorageSync('token', res.data); //儲存返回的token
resolve(res);
}
})
} else {
console.log('獲取用戶登錄態(tài)失敗晌柬!' + res.errMsg);
reject('error');
}
}
})
}
})
})
}
})
接下來在index.js中處理
const app = getApp();
Page({
onLoad: function(){
let token = wx.getStorageSync('token');
if (token == ''){
//第一次登錄姥份,獲取登錄狀態(tài)
app.getToken().then(function (res) {
_this.getData(); //此時token必然已經獲取到,且getData()在此時才會執(zhí)行
})
}else{
//有token的情況直接獲取數據
_this.getData();
}
},
//獲取數據
getData: function(){
wx.request({
header: {
'token': wx.getStorageSync('token')
},
url: 'https://xxxxx.xxxxx',
method: 'GET',
success: res => {
console.log(res);
}
})
}
})
這時候清除一下開發(fā)工具的緩存年碘,再次編譯頁面澈歉,打開調試面板的network,可以看到index.js
中的wx.request
請求是在wx.login()
的success后才開始的盛泡,這樣就達到了我們的目的闷祥,問題解決。