周嵐
(江蘇聯(lián)合職業(yè)技術(shù)學(xué)院徐州財(cái)經(jīng)分院,江蘇 徐州 221008)
關(guān)鍵字:Promise;異步回調(diào);異步請(qǐng)求;微信小程序
微信小程序已被廣泛應(yīng)用,在使用過(guò)程中信息登錄必不可少,那么,在微信小程序登錄過(guò)程中獲取微信用戶信息時(shí),需要進(jìn)行多個(gè)有關(guān)聯(lián)的異步請(qǐng)求操作,獲取用戶加密信息,然后對(duì)其解密并返回。傳統(tǒng)的異步回調(diào)嵌套方法造成程序可讀性差,程序執(zhí)行性能低下。而Promise在Javascript中主要是解決回調(diào)地獄?;卣{(diào)地獄即異步任務(wù)的層層嵌套導(dǎo)致代碼臃腫問(wèn)題,而Promise鏈?zhǔn)秸{(diào)用可以很好地解決這種代碼問(wèn)題,它解決了微信小程序獲取微信用戶信息時(shí)多個(gè)異步操作請(qǐng)求問(wèn)題,對(duì)異步請(qǐng)求功能劃分更明確,大大提高了程序的可讀性,并提供了良好的錯(cuò)誤處理邏輯。
ECMAscript 6原生提供了Promise對(duì)象。Promise對(duì)象代表了未來(lái)將要發(fā)生的事件,用來(lái)傳遞異步操作的消息。Promise對(duì)象有三種狀態(tài):pending,初始狀態(tài);fulfilled,操作成功完成狀態(tài)[1];rejected,操作失敗狀態(tài)。只有異步操作的結(jié)果可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無(wú)法改變這種狀態(tài)。Promise的出現(xiàn)解決了傳統(tǒng)Javascript異步回調(diào)嵌套模式,大大提高了程序的可讀性[2]。比如,通過(guò)下面代碼獲取當(dāng)前日期的程序來(lái)模擬Javascript傳統(tǒng)異步回調(diào)操作,具體代碼如下://setTimeout()是屬于window的method,但我們都是略去window這頂層物件名稱,這是用來(lái)設(shè)定一個(gè)時(shí)間,時(shí)間到了,就會(huì)執(zhí)行一個(gè)指定的method。
在上面的程序中,要獲取年月日的信息,需要等待3秒鐘才可以返回,代碼嵌套層數(shù)較多,可讀性較差,如果我們采用Promise來(lái)改寫(xiě),將會(huì)大大提高代碼的可讀性,具體代碼如下:
使用Promise來(lái)實(shí)現(xiàn)Javascript異步操作,對(duì)函數(shù)的功能劃分更清晰,大大提高了程序的可讀性。
微信小程序在登錄獲取微信用戶信息時(shí),需要將wx.login()函數(shù)生成code值、APPID和APPSecret發(fā)送到微信服務(wù)器,微信服務(wù)器將返回用戶信息的加密字符串,然后小程序再次將加密的用戶信息字符串發(fā)送到第三方服務(wù)器進(jìn)行解密并返回用戶的基本信息,具體時(shí)序圖如圖1所示。
圖1 微信小程序獲取用戶信息時(shí)序圖
當(dāng)用戶小程序在獲取用戶信息時(shí),尤其是敏感信息,需要先進(jìn)行wx.login()異步請(qǐng)求操作,當(dāng)微信服務(wù)器返回用戶openID和session_key后,再次進(jìn)行wx.getUserInfo()請(qǐng)求用戶基本信息,返回的基本信息對(duì)敏感信息進(jìn)行了加密,所以根據(jù)返回的加密信息encryptedData和解密算法的初始向量iv再次請(qǐng)求第三方服務(wù)器進(jìn)行解密操作,最終將用戶信息返回。在進(jìn)行wx.login()和wx.getUserInfo()有先后的順序,并且在服務(wù)端wx.getUserInfo()要用到wx.login()請(qǐng)求返回的session_key,所以在客戶端小程序中采用了Promise按照先后順序依次進(jìn)行異步請(qǐng)求[3]。
在微信小程序登錄過(guò)程中獲取用戶信息主要分為三步:微信登錄,獲取加密的用戶信息和解密用戶信息。
當(dāng)小程序啟動(dòng)時(shí),首先調(diào)用wx.login()函數(shù),返回用戶openID和session_key,但是根據(jù)官方文檔要求,盡量不要在網(wǎng)絡(luò)上傳輸session_key,可以將其保存在服務(wù)器端,并將返回的數(shù)據(jù)作為下次異步請(qǐng)求的參數(shù)[4],具體代碼如下:
當(dāng)請(qǐng)求響應(yīng)成功后,返回的數(shù)據(jù)格式是Json數(shù)據(jù)格式,包含了openId和請(qǐng)求的code值,在請(qǐng)求獲取用戶信息時(shí)作為參數(shù)傳遞進(jìn)去[5]。
wx.getUserInfo()用戶獲取用戶基本信息時(shí),首先會(huì)詢問(wèn)用戶授權(quán),如果用戶授權(quán)同意獲取微信基本信息,將返回用戶的基本信息,但是不包含openId和unionId等敏感信息[6],具體代碼如下:
將getOpenID函數(shù)返回的值以及wx.getUserInfo()返回的userInfo信息作為數(shù)組參數(shù)下一次解密用戶信息的異步請(qǐng)求[7]。
wx.getUserInfo()將返回的encryptedData信息和解密算法的初始向量iv傳遞到服務(wù)器端進(jìn)行解密,具體代碼如下:
當(dāng)小程序在啟動(dòng)時(shí),使用Promise實(shí)現(xiàn)了獲取用戶基本信息的多個(gè)異步請(qǐng)求操作,具體代碼如下:
使用Promise既保證了異步請(qǐng)求的有效性,同時(shí)又大大提高了代碼的可讀性。
本文通過(guò)對(duì)Javascript中的Promise對(duì)象的介紹,并結(jié)合微信小程序在登錄過(guò)程中獲取用戶信息的多個(gè)異步請(qǐng)求,解決了多個(gè)異步請(qǐng)求的順序執(zhí)行,保證了數(shù)據(jù)傳遞的有效性,并有效提高了代碼的可讀性。