跳到主要内容

应用通知API

桌面系统统一通知方法​

  • 桌面系统通知工厂函数,用于创建并管理原生系统通知
ts
export function createDesktopNotification(
options: DesktopNotificationOptions,
onClick?: () => void,
): DesktopNotificationHandle {
const notification = new Notification(options);

if (onClick) {
notification.on("click", onClick);
}

return {
show: () => {
const release = retainNotification(notification);

return new Promise((resolve, reject) => {
let settled = false;
let settleTimer: NodeJS.Timeout | null = null;

const settle = (callback: () => void) => {
if (settled) return;
settled = true;
if (settleTimer) {
clearTimeout(settleTimer);
settleTimer = null;
}
callback();
};

notification.once("show", () => {
settle(resolve);
});

// `failed` 事件仅 Windows 平台支持,macOS 通知失败不会触发此事件。
if (process.platform === "win32") {
notification.once("failed", (_event, error) => {
release();
settle(() => {
reject(new Error(error || "桌面通知发送失败"));
});
});
}

// macOS:如果通知被系统静默拦截,show 事件仍会触发但通知不可见。
// 通过检查应用是否真正获得通知授权来判断。
if (process.platform === "darwin") {
// 等待 show 事件后,额外检查通知是否真正显示
notification.once("show", () => {
// macOS 上 show 事件触发后,给系统一点时间展示通知
// 如果通知被权限拦截,用户需要在系统偏好设置中授权
setTimeout(() => {
settle(resolve);
}, 100);
});
}

// 如果底层系统既没有确认展示也没有返回失败,避免测试按钮一直等待。
settleTimer = setTimeout(() => {
release();
settle(() => {
// macOS 上超时可能是权限问题,提供更详细的错误信息
if (process.platform === "darwin") {
reject(
new Error(
"桌面通知发送超时,请检查 macOS 系统偏好设置中的通知权限",
),
);
} else {
reject(new Error("桌面通知发送超时"));
}
});
}, 5_000);
settleTimer.unref?.();

try {
notification.show();
} catch (error) {
release();
settle(() => {
reject(error);
});
}
});
},
};
}

相关API​

ts
notification.on('show', () => {
// 通知显示时触发
});

notification.on('click', () => {
// 用户点击通知时触发
});

notification.on('close', () => {
// 通知关闭时触发(包括用户手动关闭和自动消失)
});

// 仅 Windows
notification.on('failed', (event, error) => {
// 通知发送失败时触发
});