-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
建议嵌入块中的js支持异步函数,并且错误信息打印到控制台 #13775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
补充说明一点嵌入块中有时可能需要使用第三方的js或代码片段,但嵌入块中无法保证其他的代码片段都已加载后才执行,这样的话,就可能报错第三方函数不存在。 建议new Function中传入一个等待函数,比如whenExist函数,这样的话 需要第三方函数时,可以这样 await whenExist(()=>alasql!==undefined); 否则,需要在每个函数体中都写一遍类似whenExist这个函数,挺麻烦的,最主要的是对小白用户不友好,如果改进后,结合第三方插件或js代码,这个嵌入查询的体验能大大改善,使用体验能逼近obsidian的dataview了,通过alasql能实现对数据库和表格的sql查询甚至连表,对于做统计和汇总来说非常方便,体验也好。 现在的问题是,这个查询功能,主要业务还没开始,得塞进去一大堆业务无关的代码,小白用户光看这些业务无关的代码就看晕了,何况使用。 whenExist函数参考如下: // 等待元素或变量存在
function whenExist(selector, parentNode = null, timeout = 5000, errorMsg = '') {
return new Promise((resolve, reject) => {
let timeoutId;
let isResolved = false;
const check = () => {
let element = null;
if (typeof selector === 'function') {
element = selector();
} else {
element = (parentNode||document).querySelector(selector);
}
if (element) {
isResolved = true;
if(timeoutId) clearTimeout(timeoutId);
resolve(element);
} else {
requestAnimationFrame(check);
}
};
check();
// 设置超时兜底
if(timeout > 0) timeoutId = setTimeout(() => {
if(isResolved) return;
console.error(errorMsg||`Element not found within ${timeout}ms`);
reject(new Error(errorMsg||`Element not found within ${timeout}ms`));
}, timeout);
});
} |
再提一点,如果能传入是加载,还是用户点击执行的参数,就更好了。这一点在做是否自动加载时很有用。 我现在是通过嵌入块是否第一次被加载或第一次被动态加载来判断的,虽然已经实现了,如果有原生支持就最好了。 如果不好加就算了。 |
@frostime 邀请参与讨论该提案 |
建议官方认真考虑下。 最主要的是对小白用户不友好,如果改进后,结合第三方插件或js代码,这个嵌入查询的体验能大大改善,使用体验能逼近obsidian的dataview了,通过alasql能实现对数据库和表格的sql查询甚至连表,对于做统计和汇总来说非常方便,体验也好。 现在的问题是,这个查询功能,主要业务还没开始,得塞进去一大堆业务无关的代码,小白用户光看这些业务无关的代码就看晕了,何况使用。 |
Issue 标题提出的两点我都同意,而且实现起来应该也不复杂。
后面他提到的内容,我没有太抓住要点。 首先,我对 可能是思考角度不一样,总之这一点上我 GET 不到。 对于「传入加载类型参数」的建议,我认为需要谨慎对待。虽然实现细节有待商榷,但必须坚持一个原则: 不过,你提到的「能传入是加载,还是用户点击执行的参数」似乎没有考虑周全。 在我的印象中会造成嵌入块刷新的场景不是两种,而是三种:
|
@frostime 感谢巨佬的回复! 不愧是巨佬,研究的就是深入。 这里我解释下whenExist的必要性。 这个场景主要是在第一次加载时,比如刷新页面时,刚好有个文档是当前页面,且该页面中有嵌入块,且该嵌入块依赖第三方代码。 比如,当我在嵌入块中写一个代码,但这个代码需要依赖第三方代码,但第三方代码并不一定在嵌入块的代码执行时已经加载完毕。这时候就会报错第三方库的函数不存在。虽然通过一定的延迟或报错后手动刷新重新执行就解决了。 但报错也产生了,对于不明白原理的用户看到的可能就是报错信息和未按预期执行,并不知道需要刷新下就能解决。 如果要解决这个问题,就需要用户手动添加延迟代码或写等待第三库加载完毕的代码,而这个whenExist就是这个代码,就是为了等待第三方库加载完毕的。如果嵌入块函数体中没有自带这个函数,那么这个函数就要用户自己实现,且不说是否好实现,每个嵌入块中都写入一次也麻烦不是。因此,建议官方加入这样一个函数,减少用户的工作,对用户的使用体验也更加友好。 另外,这个whenExist并不会影响嵌入块第二次及之后的刷新情况,因为这个函数中,每次刷新都会首先检查一次目标函数是否已存在,已存在就跳过了,直接执行后面的代码,只有当目标函数不存在时才会停下来,等待目标函数出现后才继续执行后面的代码。 关于职责边界问题,我同意巨佬的观点,底层不应该依赖上层,但不知这里在调用blockRender的地方是否方便参数传入?也正如F佬说的那样,自动更新的块刷新获取不到。关于自动同步,我也找过代码,没找到。 @88250 能否给点指导? @frostime 感谢提供的嵌入块刷新场景!自动更新的刷新之前确实没考虑到这一点。 |
后台更新块的场景比如搜索替换、修改定义块关联更新引用处的锚文本等,目前没有统一机制能够通知前端,这个我觉得暂时还是靠用户手动刷新吧。 |
好的,感谢D大的回复,我是本来是想在嵌入块代码里判断是用户手动刷新还是系统自动刷新的,然后针对不同情况做不同处理,如果不好处理就算了,这个问题不大,使用场景并不多。 |
In what scenarios do you need this feature?
如图
先说异步函数
参见源代码
修改前在new function函数体中只能这样使用
修改后可以这样使用
显然后者更简洁和优雅。
再说错误信息
参见源代码
思源拦截了错误信息,既无抛出错误也无打印错误信息,只是返回了空数组,界面显示就是没匹配任何内容。
这个非常不友好,如果函数体内有语法错误,应该输出到控制台,这样开发起来更方便。
要想捕获错误,必须自己在代码中try{}catch(e){},如下,非常麻烦,尤其对小白用户,非常不友好。
Describe the optimal solution
嵌入块中的js支持异步函数,并且错误信息打印到控制台
Describe the candidate solution
No response
Other information
No response
The text was updated successfully, but these errors were encountered: