在JavaScript中,提供了一些異步特性,因為同步操作會對程序的執行進行阻塞處理。比如在瀏覽器頁面程序中,如果一段同步的代碼需要執行很長時間(比如一個很大的循環操作),則頁面會產生卡死的現象。
異步為程序提供了性能和體驗上的益處,比如可以將代碼放到setTimeout()中執行;或者在網頁中,我們使用Ajax的方式向服務器端做異步數據請求。這些異步的代碼不會阻塞當前的界面主進程,界面還是可以靈活的進行操作,等到異步代碼執行完成,再做相應的處理。
舉一個例子:在小程序中,我們獲取到后臺的數據使用時間往往是不定的,這個時候:即使你在前面寫的代碼,也可能會在后面執行。
function getAccountInfo(callback, errorCallback) { wx.request({ url: '/accounts/12345', success: function (res) { console("1") }, fail: function (res) { //... errorCallback(data); } });console.log("2")}也就是存在2輸出在1前面的可能。這種策略提升頁面加載速度。能很好的提高用戶體驗感。
但是請看下面的情景:
小程序是提倡不獲取用戶信息就能使用的,但是在特定的情況下我們必須要拿到用戶的一些數據,比如名稱,圖像鏈接等等。在這種情況下,我們首先獲取用戶的code,根據code去后臺獲取用戶的openid或者unionid。拿到這些數據之后我們才能確定用戶的身份,然后再去發新的請求(這些請求往往是需要用戶身份憑證的,比如Token)。
上面的敘述中,我們發了三次請求,第一次獲取code,第二次獲取openID或unionid,第三次根據身份信息執行新的請求。我們都知道JS中的請求都是異步執行的,有可能微信服務端的code還沒返回,用戶已經去執行一些需要權限的操作,這就會導致請求失敗。那么小程序該如何解決這種問題呢?這里提供三種方案以供參考:
1.服務端一次請求全部處理。(使用范圍太小)
2.客戶端在請求成功的回調中,再次發送請求。(可用,但是代碼會很冗長且不容易維護)
3.使用Promise
方案一中:比如用戶留言功能,我們拿到code和留言內容后全部發給服務端,服務端開啟一個新的線程去處理這些業務邏輯,主線程直接返回用戶留言成功的提示(這里不考慮新線程執行失敗的情況)。
方案二和方案三功能上是相同的,但是代碼的展示上可能方案三更加好一些。看下面的代碼(其中postReq和getReq是自己封裝的請求方法):
var http = require('request.js')function userLogin(name, image, gender, content, artilceId){ //獲取code var promise = new Promise(function(resolve,reject){ wx.login({ success: res => { resolve(res.code); } }) }) //獲取用戶身份憑證 var pm2 = promise.then(function(res){ return new Promise(function (resolve, reject){ http.postReq("user/getUserInfo", { "code": res, "type": 1, "name": name, "image": image, "gender": gender }, function (res) { // console.log(res) if (res.data == "") { wx.showModal({ title: '提示', content: '授權失敗,請重試', }) return; } resolve(res); }) }) },function(res){ }) //發表評論 pm2.then(function(res){ // console.log(res.data+":"+content) http.postReq("user/comment", { "content": content, "openId": res.data, "artilceId": artilceId},function(res){ // console.log(res) if(res.data ){ wx.getStorage({ key: 'showInfo', success: function(res) { console.log(res.data ) if(res.data != false){ wx.showModal({ title: '提示', content: '為了維護每天學Java的學習氛圍,我們已發郵件提醒管理員對評論進行審核,通過后即可展示您的評論。', }) } },fail:function(res){ wx.setStorage({ key: 'showInfo', data: false, }) wx.showModal({ title: '提示', content: '為了維護每天學Java的學習氛圍,我們已發郵件提醒管理員對評論進行審核,通過后即可展示您的評論。', }) } }) } }) }, function(res){ })} module.exports = { userLogin: userLogin}
新聞熱點
疑難解答
圖片精選