由于云函数有一项计费规则是按调用次数计费,在小程序访问量比较小的情况下还比较无所谓,但当体量上来之后不得不考虑控制一下对公共接口的调用次数从而减少一些不必要的开销。比如获取用户信息接口、获取配置信息接口
这里分享一个我自己几个小程序用到的方法,公共接口的调用都放在app.js,然后提供函数供其他页面调用。同时由于异步问题,有可能页面加载完接口还未返回,因此还需能够注册回调函数,在接口返回数据后回调给调用页面
代码示例:
app.js
App({
onLaunch: async function (options) {
//判断是否需要更新小程序
updateCheck.check();
await api.wxCloudInit();
//获取用户信息
this._getUserInfo().catch(res => {
console.warn("获取用户信息失败,准备重试");
this._getUserInfo().then();
});
},
/**
* 获取用户信息
* @param callback
* @param refresh 等于true时表示重新查询用户信息,同时也会更新会员状态
*/
getUserInfo: function (callback, refresh) {
if (!refresh) {
const userInfo = this.globalData.userInfo;
if (!userInfo.ready) {
if (typeof callback == 'function') {
this.callbackFunctions.userInfoReadyCallback.push(callback);
}
if (!this.userInfoReadyCallback) {
this.userInfoReadyCallback = res => {
console.log("获取用户信息完毕,开始回调", res);
const callbacks = this.callbackFunctions.userInfoReadyCallback;
while (callbacks.length) {
const callback = callbacks.pop();
typeof callback == 'function' && callback(res);
}
/*callbacks.forEach(callback => {
typeof callback == 'function' && callback(res);
})*/
}
console.log("注册userInfoReadyCallback成功");
} else {
console.log("已经注册了userInfoReadyCallback,不再重复注册");
}
} else {
typeof callback == 'function' && callback(userInfo);
}
} else {
console.log("准备更新用户信息")
this._getUserInfo().then(userInfo => {
typeof callback == 'function' && callback(userInfo);
});
}
},
/**
* 执行云函数,获取用户信息
* @returns {Promise<unknown>}
* @private
*/
_getUserInfo: function () {
return new Promise((resolve, reject) => {
api.callCloudUserCenterFunction("UserInfoHandler/getUserInfo", {}, res => {
console.log("获取用户数据完毕:", res.result);
const result = res.result;
if (result.success) {
const data = result.data;
this.globalData.userInfo = data;
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(data);
}
resolve(data);
} else {
console.error("没有获取到用户信息");
reject("没有获取到用户信息");
}
}, e => {
console.error("获取用户信息失败", e);
reject("获取用户信息失败");
});
});
},
/**
* 异步事件回调函数列表
* 增加这个列表是为了避免不同地方同时调用,互相覆盖回调函数
*/
callbackFunctions: {
//用户信息异步回调
userInfoReadyCallback: [],
},
globalData: {
userInfo: {
confirm: false//用来标记用户信息查询动作是否已经结束,等于true时,userInfo才可信
},
}
})
某page.js
app.getUserInfo(res => {
const isVip = res.isVip;
if (isVip) {
console.log("已开通会员", res);
}
});