【发布时间】:2021-06-10 23:55:54
【问题描述】:
我经常编写异步模块,由于它们的异步特性,我会在一些初始化代码期间请求、解析并分配这些模块。例如:
var asynchronousModule;
function doSomethingUsingMyLoadedModule() {
// Ideally intellisense would be able to do its thing for asynchronousModule right here
asynchronousModule._doSomething();
}
// initializer
(async () => {
asynchrousModule = await require('my-custom-async-module');
})();
但是,由于 asynchronousModule 直到 doSomethingUsingMyLoadedModule 函数声明后才被分配,智能感知无法在该函数内自动完成/自动填充 asynchronousModule。
所以我想知道是否有一种方法可以明确告诉智能感知过早在声明时为我们的变量赋值,使用 inline-cmets 或类似的方法。例如,第一行是这样的:
var asynchronousModule; // vsc-intellisense assign-async-import my-custom-async-module
那太棒了,但可能是一厢情愿。但是,也许还有其他方法可以将智能感知用于异步模块,而不必将我的整个文件包装在异步函数中?我的意思是把我的代码重写成这样的:
(async () => {
const asynchrousModule = await require('my-custom-async-module');
function doSomethingUsingMyLoadedModule() {
asynchrousModule._doSomething();
}
})();
虽然这可以让智能感知工作,而且在这个例子中看起来确实不错,但我真的不喜欢用标签覆盖整个文件的内容,尤其是当文件变大时,所以这不是我理想的解决方案。
【问题讨论】:
-
为什么需要
await require('my-custom-async-module');,await有什么用 -
@rioV8 该模块是异步的,因此它返回一个承诺。因此,我需要等待才能解决承诺。作为一个示例用例,也许我的模块建立并保留了一个数据库连接,这样我就可以在多个文件中重用这个相同的连接。因为建立一个 DB 连接是异步的,所以该模块会导出一个 Promise,它将解析到该 DB 连接中。因此,通过 await 或通过 promise.then 解决 promise 是获取模块实际有用部分的必要条件。
-
在
_doSomething()函数中处理promise。模块应该写成导出不包含 Promise。加载模块时不要建立数据库连接,而是在需要它的函数内部,缓存数据库连接的结果 -
@rioV8 这可行,但我认为这不是最佳选择。假设我的模块现在是同步的,但它的唯一目的是通过其唯一的方法
_doSomething()公开和缓存共享数据库连接。尽管连接在第一次调用后被缓存,_doSomething()仍然会在后续调用中返回一个承诺(否则我将不断地检查它的返回类型)。尽管等待单个已解决的 Promise 的开销可以忽略不计,但现在想象一下以这种方式构建的一系列依赖模块,每个模块都在等待下一个已解决的 Promise。
标签: javascript node.js asynchronous visual-studio-code intellisense