|
見到(dao)wx.request的第一眼,就讓我想起了(le)$.ajax這東西,使用起來確(que)實有很(hen)多不方便,不能忍(ren),幸好小(xiao)程序是支持ES6語法(fa)的,所(suo)以可以使用promise稍(shao)加(jia)改造。 先(xian)來(lai)說說wx.request為(wei)什么不能忍(ren)。 鋪墊:“看得見卻抓不住“的異步請求
然后我們會(hui)在控制臺到這樣的結果:
這其實是(shi)一個很簡(jian)單(dan)的異(yi)步問題,wx.request是(shi)異(yi)步請求,JS不會(hui)等(deng)待wx.request執行(xing)完畢再往下執行(xing),所以JS按順序(xu)會(hui)先執行(xing)this.loadMyData(),等(deng)服務器返(fan)回數據以后,loadMyData()早就(jiu)執行(xing)完了,當然也就(jiu)沒(mei)有拿到值啦。 其(qi)實我們在同(tong)步(bu)流程中(zhong)才說(shuo)“返(fan)回(hui)(hui)”,異(yi)(yi)步(bu)沒(mei)有“返(fan)回(hui)(hui)”這個(ge)概(gai)念(或者(zhe)說(shuo)異(yi)(yi)步(bu)返(fan)回(hui)(hui)是沒(mei)有意義的(de)),異(yi)(yi)步(bu)對應的(de)是“回(hui)(hui)調(diao)”,也就(jiu)是說(shuo),對于一個(ge)異(yi)(yi)步(bu)函數,我們應該傳(chuan)入一個(ge)“回(hui)(hui)調(diao)函數”來接(jie)收結果。 初步解決:通過回調接收結果最簡單(dan)的(de)解決(jue)方案,就是把需要(yao)使(shi)用異步數(shu)據的(de)函數(shu)寫在回調里:
這(zhe)樣(yang)就可(ke)以正確輸出了:
但是(shi)如(ru)果邏輯復雜,需(xu)要多(duo)層異步操(cao)作(zuo),會出現怎么(me)樣的情況呢?
有(you)(you)沒有(you)(you)感覺頭皮發麻?什么(me)優雅什么(me)可讀性(xing),瞬間蕩然無存,這(zhe)就(jiu)是恐怖的“回(hui)調(diao)地獄(yu)”(Callback Hell)。 而我(wo)們發(fa)現,微(wei)信小(xiao)程序(xu)的網絡請求(qiu)wx.request,也(ye)正(zheng)是這(zhe)種依靠回調函數的形式,類似于(yu)以前的$.ajax,它在邏(luo)輯復雜、頁面執行(xing)順(shun)序(xu)要求(qiu)多的情況下,弊端也(ye)是很明顯的。不(bu)過好在小(xiao)程序(xu)支持ES6,我(wo)們可以盡情地擁(yong)抱(bao)Promise! 使用Promise包裝wx.requestPromise這東西簡單說來就(jiu)是,它可以將異步的(de)(de)(de)執行邏輯(ji)和結果處(chu)理分離,摒棄了(le)一(yi)層又(you)一(yi)層的(de)(de)(de)回調嵌套,使得處(chu)理邏輯(ji)更加清晰。想具體了(le)解的(de)(de)(de)還請自行查找資料。 現(xian)在我們(men)就用Promise包裝一下wx.request:
現在再使(shi)用試(shi)試(shi):
結(jie)果和使用回(hui)調(diao)函數一致。當有多個異步請(qing)求(qiu)時,直接(jie)不斷地.then(fn)去處(chu)理即可,邏輯(ji)清晰。 當然,這里只是寫了(le)一個最簡(jian)單的(de)(de)Promise函數,還不完(wan)整。更(geng)完(wan)整的(de)(de)Promise化wx.request,等以后業務需要再完(wan)善吧。另(ling)外各種(zhong)小程序(xu)開發(fa)框(kuang)架也都有了(le)現成的(de)(de)promise化API,拿(na)來即用。 |