問題概述
基于小程序request請求是異步的特性,app.js onLaunch()
中的請求與index.js onLoad()
中的請求是同時進行的,導致onLoad()
中如果有基于onLaunch()
返回的數據的請求,會有報錯,這樣會使onLoad()
中request請求的數據“第一次”無法正常獲取。
我的小程序中所有的requset請求都需要在header中帶著用戶唯一的token進行發起,而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 對象的狀態,從「未完成」變為「成功」(即從 pending 變為 resolved);
- 如果異步操作失敗,則用 reject 方法將 Promise 對象的狀態,從「未完成」變為「失敗」(即從 pending 變為 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 => {
// 發送 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('獲取用戶登錄態失?。? + res.errMsg);
reject('error');
}
}
})
}
})
})
}
})
接下來在index.js中處理
const app = getApp();
Page({
onLoad: function(){
let token = wx.getStorageSync('token');
if (token == ''){
//第一次登錄,獲取登錄狀態
app.getToken().then(function (res) {
_this.getData(); //此時token必然已經獲取到,且getData()在此時才會執行
})
}else{
//有token的情況直接獲取數據
_this.getData();
}
},
//獲取數據
getData: function(){
wx.request({
header: {
'token': wx.getStorageSync('token')
},
url: 'https://xxxxx.xxxxx',
method: 'GET',
success: res => {
console.log(res);
}
})
}
})
這時候清除一下開發工具的緩存,再次編譯頁面,打開調試面板的network,可以看到index.js
中的wx.request
請求是在wx.login()
的success后才開始的,這樣就達到了我們的目的,問題解決。