js
// 调用示例,当callback返回true时退出,返回false时取消退出
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
listenExit(async () => {
console.log('waiting');
await sleep(30000);
return true;
});
// 监听思源退出事件,退出前执行callback,当callback返回true时退出,返回false时取消退出(仅支持electron客户端)
// see https://github.com/siyuan-note/siyuan/blob/5129ad926a21176a352cf5f630e0651011bf9c83/app/src/dialog/processSystem.ts#L287
function listenExit(callback) {
if(!navigator.userAgent.includes('Electron')) return;
// 内核是否已退出
let isKernelExited = false;
// 是否已取消退出
let isCancelExited = false;
// 监听内核退出
const originalFetch = window.fetch;
window.fetch = async function (url, ...args) {
try {
if(url.endsWith('/api/system/exit')) {
for(;;) {
if(await callback()) {
isKernelExited = true;
break;
} else {
isCancelExited = true;
break;
}
await sleep(200);
}
if(isCancelExited) return new Promise(rs => rs({code:0,msg:'',data:null}));
}
const response = await originalFetch(url, ...args);
return response;
} catch (error) {
throw error;
}
};
// 监听客户端退出
// 保存原始方法
const ipcRenderer = require('electron').ipcRenderer;
const originalSend = ipcRenderer.send;
// 重写 ipcRenderer.send 方法
ipcRenderer.send = async function (...args) {
if(args[0] === 'siyuan-quit'){
for(;;) {
if(isKernelExited) {
await sleep(400);
break;
} else if(isCancelExited) {
return;
}
await sleep(200);
}
originalSend.apply(ipcRenderer, args);
} else {
originalSend.apply(ipcRenderer, args);
}
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}