开发小伙伴们 👋,是不是也踩过这个坑👇:小程序刚启动时在 app.js 做全局初始化,但首页 onLoad 取不到初始化后的数据,导致页面逻辑出错!
我用 Promise + 发布订阅模式,完美解决!💥
🌟 小程序启动时,我需要在 onLaunch() 做这些事:
✅ 检查小程序更新 ✅ 拉取基础配置 ✅ 获取用户或系统状态
BUT!初始化是 异步 的,而首页 index.js 的 onLoad() 生命周期太快,可能比初始化还早一步。直接用 getApp() 拿不到数据,页面全空 ❌。💡 解决方案: 用发布订阅模式通知页面 —— 初始化完成再动!
🔥 实现核心:
1️⃣ Promise 封装初始化,明确完成时机 2️⃣ 自己实现简易版 EventBus,支持 on / emit 3️⃣ 初始化成功后 emit 发布事件,页面收到通知,再用数据
📄 步骤拆解:
1️⃣ 封装初始化函数 📌 重点:重试机制,确保 getApp() 可用。
// utils/appInit.js
function initFun() {
const app = getApp();
app.globalData.pageInit = true;
}
function appInit(maxRetry = 10, interval = 250) {
return new Promise((resolve, reject) => {
let retryCount = 0;
const checkAppReady = () => {
wx.nextTick(() => {
if (typeof getApp === 'function' && getApp() !== undefined) {
initFun();
resolve('初始化成功');
} else if (retryCount < maxRetry) {
retryCount++;
setTimeout(checkAppReady, interval);
} else {
reject('初始化失败');
}
});
};
checkAppReady();
});
}
export default appInit;
2️⃣ 实现简易版 EventBus 📌 功能:订阅 on / 发布 emit / 取消 off,页面间轻松通信。
// utils/eventBus.js
class EventBus {
constructor() {
this.events = {};
}
on(event, callback) {
if (typeof event !== 'string' || typeof callback !== 'function') return;
if (!this.events[event]) {
this.events[event] = [];
}
if (!this.events[event].includes(callback)) {
this.events[event].push(callback);
}
}
emit(event, data) {
if (!this.events[event] || this.events[event].length === 0) return;
this.events[event].forEach(cb => {
try {
cb(data);
} catch (err) {
console.error(`"${event}" 回调出错`, err);
}
});
}
off(event, callback) {
if (!this.events[event]) return;
this.events[event] = this.events[event].filter(fn => fn !== callback);
}
}
const eventBus = new EventBus();
export default eventBus;
3️⃣ App.js 使用 📌 关键点:✅ 先订阅,再初始化,防止订阅晚了漏事件。
// app.js
import appInit from '/utils/appInit';
import eventBus from '/utils/eventBus';
App({
globalData: {},
onLaunch() {
// 先订阅,保证其他页面后续能接收
eventBus.on('initDone', () => {});
appInit(10).then(() => {
eventBus.emit('initDone', { init: true });
}).catch(err => {
console.error('App 初始化失败', err);
});
},
});
4️⃣ 首页 index.js 监听初始化完成 📌 确保数据 ready,再做业务处理!
// pages/index/index.js
import eventBus from '/utils/eventBus';
Page({
onLoad() {
eventBus.on('initDone', () => {
const app = getApp();
console.log('收到初始化完成通知', app.globalData);
// 使用初始化数据
});
},
onUnload() {
// 页面销毁时解绑,防止内存泄漏
eventBus.off('initDone', ()=>{});
}
});