目的:实现在思源关闭前执行某些代码
相关帖子
-
wilsons •付费者 捐赠者
没太懂,日程不是你自己实现的插件吗?什么时候触发编辑,你自己不是可控的吗?
还是你的日程在文档中编辑的?建议描述下你的日程是什么?怎样操作的?
触发频繁,我没试过通过插件开发的方式监听,但我看官方源码大概率是 ws-main 里有很多情况被触发,你通过 data 参数里的 transactions 应该可以判断为更新操作的。
另外,通过源码可知,这个事件就是官方 ws 的 onmessage 的回调,所以,通过 onmessage 监听也应该是一样的。
比如:
siyuan.ws.ws.addEventListener('message', (e) => { const msg = JSON.parse(e.data); if(msg.cmd === "transactions") { // 这里获取更新后的数据 console.log(msg); } });
可参考 https://github.com/siyuan-note/siyuan/issues/13313#issuecomment-2515402535
如果非要关闭时生成一次的话,下面这个代码可以满足需求,该代码会拦截思源退出事件,当退出时,先执行回调代码,当完成后再继续退出。
但注意,该代码仅支持 electron 客户端,由于浏览器和手机端不好拦截暂不支持。
如果有兴趣研究,可以参考源码 https://github.com/siyuan-note/siyuan/blob/5129ad926a21176a352cf5f630e0651011bf9c83/app/src/dialog/processSystem.ts#L287
Demo 代码如下(仅支持 electron 客户端):
// 调用示例,当callback返回true时退出 listenExit(async () => { console.log('waiting'); await sleep(30000); return true; }); // 监听思源退出事件,退出前执行callback,当callback返回true时退出(仅支持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; // 监听内核退出 const originalFetch = window.fetch; window.fetch = async function (url, ...args) { try { if(url.endsWith('/api/system/exit')) { for(;;) { if(await callback()) { isKernelExited = true; break; } await sleep(200); } } 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; } await sleep(200); } originalSend.apply(ipcRenderer, args); } else { originalSend.apply(ipcRenderer, args); } }; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
虽然这个方法可行,但还是推荐之前的建议,即缩小生成时间间隔和监听日程修改事件。
- 其他回帖
-
没太懂,日程不是你自己实现的插件吗?什么时候触发编辑,你自己不是可控的吗?
还是你的日程在文档中编辑的?建议描述下你的日程是什么?怎样操作的?
触发频繁,我没试过通过插件开发的方式监听,但我看官方源码大概率是 ws-main 里有很多情况被触发,你通过 data 参数里的 transactions 应该可以判断为更新操作的。
另外,通过源码可知,这个事件就是官方 ws 的 onmessage 的回调,所以,通过 onmessage 监听也应该是一样的。
比如:
siyuan.ws.ws.addEventListener('message', (e) => { const msg = JSON.parse(e.data); if(msg.cmd === "transactions") { // 这里获取更新后的数据 console.log(msg); } });
可参考 https://github.com/siyuan-note/siyuan/issues/13313#issuecomment-2515402535
如果非要关闭时生成一次的话,下面这个代码可以满足需求,该代码会拦截思源退出事件,当退出时,先执行回调代码,当完成后再继续退出。
但注意,该代码仅支持 electron 客户端,由于浏览器和手机端不好拦截暂不支持。
如果有兴趣研究,可以参考源码 https://github.com/siyuan-note/siyuan/blob/5129ad926a21176a352cf5f630e0651011bf9c83/app/src/dialog/processSystem.ts#L287
Demo 代码如下(仅支持 electron 客户端):
// 调用示例,当callback返回true时退出 listenExit(async () => { console.log('waiting'); await sleep(30000); return true; }); // 监听思源退出事件,退出前执行callback,当callback返回true时退出(仅支持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; // 监听内核退出 const originalFetch = window.fetch; window.fetch = async function (url, ...args) { try { if(url.endsWith('/api/system/exit')) { for(;;) { if(await callback()) { isKernelExited = true; break; } await sleep(200); } } 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; } await sleep(200); } originalSend.apply(ipcRenderer, args); } else { originalSend.apply(ipcRenderer, args); } }; } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
虽然这个方法可行,但还是推荐之前的建议,即缩小生成时间间隔和监听日程修改事件。
1 回复 - 查看全部回帖