微信小程式學習總結02:封裝api請求(處理非同步api回撥地獄的一種方案)

code386發表於2020-10-27
  1. 封裝http的api請求,也就是封裝 wx.request() 函式
  2. wx.request() 這類的小程式函式,都是非同步函式,在呼叫傳值的時候需要使用回撥函式,呼叫次數多起來,會出現回撥地獄現象
    接收處理非同步函式呼叫的返回值,通常有三種途徑:
    1. 透過 callback 回撥函式處理(微信小程式本地開發和雲開發都支援)
    2. 透過 promise 物件處理(微信小程式本地開發不支援,雲開發不寫success引數即可自動返回promise物件)
    3. 透過 await和async 處理(微信小程式本地開發不支援)
  1. 透過工具類,編寫一個代理函式,將 wx.request() 這類的非同步函式程式設計返回Promise物件
  2. 當呼叫這些代理函式處理過的非同步函式時,使用await和async處理,並直接收到返回的值

URL地址:www.example.com/user/by/id?id=1
資料格式:(假設返回的是一個物件中存放著陣列)

{
    data: [
    {
        id: 1
        name: Eric
    }
    ]
}
  1. 微信開發者工具,開啟 ES6轉ES5增強編譯
    • Promise物件是es6語法,需要透過ES6轉ES5處理
    • await和async是es7的語法,需要透過增強編譯處理
  2. 建立 /config/config.js 檔案,記錄 api 請求的常用引數
  3. 建立 /utils/util.js 檔案,編寫代理函式
    • 其他檔案使用小程式非同步函式傳值的時候,呼叫該代理函式
    • 使非同步函式可以返回Promise物件
  4. 建立 /utils/http.js 檔案,編寫封裝 wx.request 函式
    • 在此檔案中,使用 /utils/util.js 中的代理函式對wx.request處理
    • 透過 await和async 的使用並return的資料
  5. 建立 /model/user.js 檔案中,處理 api 請求以及業務邏輯處理
    • 在此檔案中,使用 /utils/http.js 處理api請求並return資料
    • 如果需要額外的業務邏輯,也需要在此完成
  6. pages/user/ 資料夾中,完成資料繫結和資料展示
  1. 建立 /config/config.js 檔案,記錄 api 請求的常用引數
    // 將公用的部分常用引數放入配置檔案中
    const config = {
     apiBaseUrl: 'http://www.example.com'
    }
    export {
     config
    }
  2. 建立 /utils/util.js 檔案,編寫代理函式
    來自:Lin-UI函式庫
    /**
    *  封裝非同步函式,使其返回Promise物件
    *  以便使用 await 和 async 呼叫非同步函式
    */
    const promisic = function (func) {
    return function (params = {}) {
     return new Promise((resolve, reject) => {
       const args = Object.assign(params, {
         success: (res) => {
           resolve(res);
         },
         fail: (error) => {
           reject(error);
         }
       });
           func(args);
       });
     };
    };
    // 匯出 promisic
    export {
     promisic
    }
  3. 建立 /utils/http.js 檔案,編寫封裝 wx.request 函式
     import { config } from "../config/config";    // 獲取api基本資訊
     import { promisic } from "./util";    // 透過代理函式處理非同步函式 wx.request
     class Http {
         // 透過代理函式處理,返回的是Promis物件,需要使用await和async處理
         static async request({url, data, method='GET'}) {
             const res = await promisic(wx.request)({
               url: `${config.apiBaseUrl}${url}`,
               data,
               method
             });
             // 想要的資料是案例資料中的陣列,不是物件,所以需要在此得到物件中的陣列並返回
             return res.data;
           }
         }
         // 匯出封裝的 Http 請求類
         export {
           Http
         }
  4. 建立 /model/user.js 檔案中,處理 api 請求以及業務邏輯處理
    import { Http } from "../utils/http";
    class User {
     static async getUserById() {
         // 使用封裝好的http請求,並將其資料結果返回
         return await Http.request({
             url: `/user/by/id`,
             data: {
                 id: 1
             }
         });
     }
    }
    export {
     User
    }
  5. pages/user/user.js 資料夾,完成資料繫結
    import { User } from "../../model/user";
    Page({
     /**
     * 頁面的初始資料
     */
     data: {
         user: null
     },
     /**
     * 監聽頁面載入
     */
     onLoad: async function (options) {
         const data = await User.getUserById();
         // 陣列0是想要的具體資料
         this.setData({
             user: data[0]
         });
     }
    })
  6. pages/user/user.wxml 檔案中,完成資料展示
    <view>
     {{user.name}}
    </view>
  • /utils/util.js 中的 promisic 函式,也可以使用在其他非同步函式上來直接收到返回資料
  • 微信小程式目前版本的語法,仍然是以es5為主,所以es6的promise物件和es7的await、async都無法直接使用,需要透過配置開發者工具和特殊編寫的工具類實現
  • 在後續api請求中,除有特殊需求外,只需要從 步驟4 開始進行業務處理即可,前幾步中的配置已經完成
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章