小程式生命週期分析與註冊流程回撥

劉清朗發表於2019-03-04

小程式生命週期分析與註冊流程回撥

從小程式釋出到現在,官方api 變動了好幾個版本
首先我們先看一下小程式的生命週期

小程式生命週期分析與註冊流程回撥

app.js 為小程式的啟動入口檔案

onLauch: 小程式初始化回掉,生命週期內只執行一次 onShow: 小程式開啟或者從後臺喚起時的回撥 onHide: 小程式從前臺進入後臺時 onError: 小程式發生指令碼錯誤,或者 api 呼叫失敗時觸發,會帶上錯誤資訊

頁面生命週期:

onLoad:註冊頁面的時候執行,只執行一次 onShow: 頁面在前臺展示時執行,顯示一次執行一次 onReady: 頁面初次渲染完成時執行,冷啟動時不執行 onHide: 頁面從前臺進入後臺 onUnload: 頁面登出時執行

個人覺得 小程式app中應該增加一個onUnload週期,頁面的銷燬現實場景個人還沒有使用到

===========================================

下面我們來看一下 小程式的註冊流程

小程式生命週期分析與註冊流程回撥

針對小程式開發者看下圖

小程式生命週期分析與註冊流程回撥

1. 檢查是否是登陸介面

2. 判斷session

3. wx.login--》獲取token

4. 執行原有回掉

好處:讓後續開發者 忽略登陸流程邏輯

function doLogin(callback, obj) {
    if (obj.isLogin) {
        // 登入介面,直接放過
        // 直接放過,讓其走下去
        typeof callback === "function" && callback();
    } else if(session) {
        // 快取中有session
        if(sessionExpireTime && new Date().getTime() > sessionExpire) {
            // 如果有設定本地session快取時間,且快取時間已到
            session = '';
            doLogin(callback, obj);
        } else {
            typeof callback === "function" && callback();
        }
    } else if (logining) {
        // 正在登入中,請求輪詢稍後,避免重複呼叫登入介面
        flow.wait('doLoginFinished', function () {
            doLogin(callback, obj);
        })
    } else {
        // 快取中無session
        logining = true;
        obj.count++;
        // 記錄呼叫wx.login前的時間戳
        // 執行login 獲取code
        obj._loginStartTime = new Date().getTime();
        console.log('wx.login');
        wx.login({
            complete: function () {
                obj.count--;
                // 記錄wx.login返回資料後的時間戳,用於上報
                obj._loginEndTime = new Date().getTime();
                if (typeof reportCGI === "function") {
                    reportCGI('wx_login', obj._loginStartTime, obj._loginEndTime, request);
                }
                typeof obj.complete === "function" && obj.count == 0 && obj.complete();
            },
            success: function (res) {
                if (res.code) {
                    var data;
                    // codeToSession.data支援函式
                    // 上傳伺服器操作
                    if (typeof codeToSession.data === "function") {
                        data = codeToSession.data();
                    } else {
                        data = codeToSession.data || {};
                    }
                    data[codeToSession.codeName] = res.code;

                    obj.count++;
                    requestWrapper({
                        url: codeToSession.url,
                        data: data,
                        method: codeToSession.method,
                        isLogin: true,
                        report: codeToSession.report || codeToSession.url,
                        success: function (s) {
                            session        = s;
                            sessionIsFresh = true;
                            // 如果有設定本地session過期時間
                            if(sessionExpireTime) {
                                sessionExpire = new Date().getTime() + sessionExpireTime;
                                wx.setStorage({
                                    key: sessionExpireKey,
                                    data: sessionExpire
                                })
                            }
                            // 執行回掉
                            typeof callback === "function" && callback();
                            wx.setStorage({
                                key: sessionName,
                                data: session
                            })
                        },
                        complete: function () {
                            obj.count--;
                            typeof obj.complete === "function" && obj.count == 0 && obj.complete();
                            logining = false;
                            flow.emit('doLoginFinished');
                        },
                        fail: codeToSession.fail || null
                    });
                } else {
                    fail(obj, res);
                    console.error(res);
                    // 登入失敗,解除鎖,防止死鎖
                    logining = false;
                    flow.emit('doLoginFinished');
                }
            },
            fail: function (res) {
                fail(obj, res);
                console.error(res);
                // 登入失敗,解除鎖,防止死鎖
                logining = false;
                flow.emit('doLoginFinished');
            }
        })
    }
}
複製程式碼
處理頁面登陸互動的兩種方式

1. app.js 註冊回掉函式,進入page 註冊這個回掉函式,登陸完成執行app.logincallback

page.js
const app = new getApp()
onLoad(){
    app.loginCallback = () => {
        this.init()
    }
}

複製程式碼

這種方式可以,而且具有頁面控制的靈活性,但靈活性帶來的就是出錯的機率會增大很多

2. 在login頁面獲取登陸的前一個頁面,然後登陸完成後重新整理前一個頁面狀態

login.js

werequest.login().then(function(){
    let pages = getCurrentPages();
    let Page = pages[pages.length - 1];//當前頁
    let prevPage = pages[pages.length - 2];  //上一個頁面
    prevPage.onLoad()
})
複製程式碼

個人比較提交這種方式,因為其他頁面只需要處理自己的頁面邏輯就可以

相關文章