前言:
好長一段時間木有更新文章了,一是因為懶,二還是因為懶。
今年下來,前前后后敲了有好幾個小程序,下文算是總結(jié)下經(jīng)驗吧。
第一點是始終繞不開的網(wǎng)絡(luò)請求,這個后續(xù)新起一片文章說吧,這里想說的是通過包裝的方式,修改小程序的page參數(shù),以滿足一些特殊的需求,舉例來說,我需要給每個頁面加上用戶訪問的日志,包括跳轉(zhuǎn)到這個頁面時帶過來的關(guān)鍵參數(shù),打開小程序的方式(場景值),還可能帶上訪問頁面的手機型號或系統(tǒng)參數(shù)。
方案一
最先想到的方案是在每個頁面的onShow生命周期函數(shù)中加上日志上傳的功能,類似下面這樣:
const app = getApp()
Page({
data: {
},
onLoad: function(options) {
this.params = options;
},
onShow: function (options) {
const sysInfo = wx.getSystemInfoSync();
const path = this.route;
const scene = app.globalData.scene;
app.submitLog(this.route, scene, sysInfo, this.params);
}
})
先說說這樣寫的缺點吧:
1、每訪問一個頁面都提交一次日志,導(dǎo)致后端這個接口壓力過大;
2、每個頁面都要加上傳日志的邏輯;
考慮到每個頁面都涉及到記錄日志,所以在想著在每個頁面的Page參數(shù)里做手腳,如果可以寫一個返回符合Page參數(shù)要求的管理器,就可以在里面做我們想要的操作了。類似下面這樣:
const app = getApp()
Page(pageOptionManager({
data: {
myData: 'hello world'
},
onLoad: function(options) {
console.log('this is onLoad function');
},
onShow: function() {
console.log('this is onShow function')
}
}))
function pageOptionManager(options) {
const params = {};
params.onLoad = function (...args) {
options.onLoad.call(this, ...args);
console.log('額外的操作邏輯');
}
params.onShow = function(...args) {
options.onShow.call(this, ...args);
console.log('額外的操作邏輯');
}
...
}
為了方便說明,去掉了判斷的邏輯,只列出了關(guān)鍵的步驟,實際做的時候可以抽出一個專門的文件來處理這個參數(shù)邏輯,具體代碼小的po到github了。
再來看看第一個“每次頁面跳轉(zhuǎn)都請求日志上傳接口導(dǎo)致后端壓力過大”的問題。最直接的方式就是降低接口請求的頻率,這就要求我們在每次頁面跳轉(zhuǎn)的時候把日志收集起來,等到一定的時間再統(tǒng)一上傳,或者到了某些特定的條件,比如退出小程序前。關(guān)鍵代碼如下:
import SysInfoH from "../sys-infos-helper.js";
class LogManager {
// 使用單例,控制日志的邏輯沒必要new多個實例
static getInstance() {
if(LogManager.instance) {
return LogManager.instance;
} else {
LogManager.instance = new LogManager();
return LogManager.instance
}
}
// 收集日志
addVisitLog(path, params) {
this.visitLog = {
path: path,
params: params,
createTime: new Date().getTime()
};
this.visitlogs || (this.visitlogs = []);
this.visitlogs.push(this.visitLog);
// 設(shè)置提交日志的條件
if (this.visitlogs.length >= 20) {
this.submitVisit();
} else if (!this.visitlogTid) {
this.visitlogTid = setTimeout(this.submitVisit.bind(this), 3000);
}
}
// 提供提交日志的api以便外部在需要立即提交日志的時候調(diào)用
submitVisit() {
if (this.visitlogTid) {
clearTimeout(this.visitlogTid);
delete this.visitlogTid;
}
if (this.visitlogs && this.visitlogs.length > 0) {
const visitlogs = this.visitlogs;
this.visitlogs = [];
console.log('submit visit log');
}
}
}
export default LogManager.getInstance();
關(guān)鍵點加上了注釋,具體可以根據(jù)個人需要設(shè)計,比如日志需要記錄的參數(shù)等。相關(guān)代碼小的也po到github了。