午夜91福利视频,午夜成人在线观看,午夜在线视频免费观看,午夜福利短视频,精品午夜成人免费视频APP

小程序模板網

微信小程序踩坑系列——從wx.request談談異步處理

發布時間:2018-10-07 09:27 所屬欄目:小程序開發教程

見到(dao)wx.request的第一眼,就讓我想起了(le)$.ajax這東西,使用起來確(que)實有很(hen)多不方便,不能忍(ren),幸好小(xiao)程序是支持ES6語法(fa)的,所(suo)以可以使用promise稍(shao)加(jia)改造。

先(xian)來(lai)說說wx.request為(wei)什么不能忍(ren)。

鋪墊:“看得見卻抓不住“的異步請求


Page({
  data: {
    myData: ''
  },
  // loadMyData函數用于打印myData的值
  loadMyData () {
    console.log('獲取到的數據為:' + this.data.myData)
  },
  // 生命周期函數onload用于監聽頁面加載
  onload: function () {
    wx.request({
      url: '//api',  // 某個api接口地址
      success: res => {
        console.log(res.data)
        this.setData({
          myData: res.data
        })
        console.log(this.data.myData)
      }
    })
    // 調用之前的函數
    this.loadMyData()
  }
})

然后我們會(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)寫在回調里:


...
onload: function () {
  wx.request({
    url: '//api',  // 某個api接口地址
    success: res => {
      console.log(res.data)
      this.setData({
        myData: res.data
      })
      console.log(this.data.myData)
      // 把使用數據的函數寫在回調函數success中
      this.loadMyData()
    }
  })
}

這(zhe)樣(yang)就可(ke)以正確輸出了:

 但是(shi)如(ru)果邏輯復雜,需(xu)要多(duo)層異步操(cao)作(zuo),會出現怎么(me)樣的情況呢?


asyncFn1(function(){
  //...
  asyncFn2(function(){
    //...
    asyncFn3(function(){
      //...
      asyncFn4(function(){
        //...
        asyncFn5(function(){
           //...
        });
      });
    });
  });
});

有(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.request

Promise這東西簡單說來就(jiu)是,它可以將異步的(de)(de)(de)執行邏輯(ji)和結果處(chu)理分離,摒棄了(le)一(yi)層又(you)一(yi)層的(de)(de)(de)回調嵌套,使得處(chu)理邏輯(ji)更加清晰。想具體了(le)解的(de)(de)(de)還請自行查找資料。

現(xian)在我們(men)就用Promise包裝一下wx.request:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * requestPromise用于將wx.request改寫成Promise方式
 * @param:{string} myUrl 接口地址
 * @return: Promise實例對象
 */
const requestPromise = myUrl => {
  // 返回一個Promise實例對象
  return new Promise((resolve, reject) => {
    wx.request({
      url: myUrl,
      success: res => resolve(res)
    })
  })
}
// 我把這個函數放在了utils.js中,這樣在需要時可以直接引入
module.exports = requestPromise

 

現在再使(shi)用試(shi)試(shi):


// 引用模塊
const utilApi = require('../../utils/util.js')
Page({
  ...
  // 生命周期函數onload用于監聽頁面加載
  onLoad: function () {
    utilApi.requestPromise("//www.bilibili.com/index/ding.json")
    // 使用.then處理結果
    .then(res => {
      console.log(res.data)
      this.setData({
        myData: res.data
      })
      console.log(this.data.myData)
      this.loadMyData()
    })
  }
})

結(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)來即用。



易優小程(cheng)序(企業(ye)版)+靈活api+前后代碼開源 碼云(yun)倉庫(ku):
本文地址://www.jinyoudianli.com/wxmini/doc/course/24850.html 復制鏈接 如需定制請聯(lian)系易優客(ke)服咨詢:

工作日 8:30-12:00 14:30-18:00
周六及(ji)部分節假日(ri)提供值班(ban)服務

易小優(you)
轉人工 ×