在这里有一个新手问题。我需要在我的Typescript文件的顶层声明常量,因此下面的所有功能都可以使用它。问题是我需要分配给该常量的值由异步函数返回,而这就是我遇到的问题。不能从顶层调用异步函数-我可以执行类似的操作,但是在这种情况下,常量不再位于顶层,并且不能被其他函数访问。
(async () => {
const myConst = await asyncFunction(params);
})();
另一种选择是使用let而不是const,就像这样,但是我宁愿在上面使用const
let myConst;
(async () => {
myConst = await asyncFunction(params);
})();
你能告诉我吗?有什么办法解决这个问题,以便我可以为全局范围声明const并根据异步函数为其分配一个值?
非常感谢:)
答案 0 :(得分:4)
在顶级变量中使用异步结果是有问题的,因为无法静态保证模块中的函数尝试读取该值时结果将准备就绪。在我看来,执行此操作的正确和安全的方法是将诺言赋给顶级变量,并使任何读取值await
的函数成为结果:
const myConst = asyncFunction(params);
async function example() {
doStuff(await myConst);
}
但是,如果要在顶级变量中获取异步结果很重要,并且您可以通过某种方法来保证该值在读取之前就已经准备好,那么我将使用您的let
赋值。在这种情况下,我认为没有什么好方法可以使该变量成为const
。
答案 1 :(得分:2)
问题在于,由于提供值的操作是异步的,因此模块中的其他函数可能会在设置值之前尝试使用变量/常量。因此,最好避免这样做,也许可以按照Jesse Hallett的建议进行操作,并强制模块中的其他函数使用promise。
如果您无法避免这种情况,并且您确定在异步操作获取值返回之前肯定不会调用这些函数,请使用let
选项用null
初始化变量或其他一些标志值,并检查在准备好并抛出它们之前应该不会调用的函数中的标志值。例如:
let myConst = null; // null or some other value that isn't valid for this
(async () => {
try {
myConst = await asyncFunction(params);
} catch (e) {
// Handle the fact the async function failed -- don't skip this!
}
})();
function assumeMyConst() {
if (myConst === null) {
throw new Error("State error: myConst not available yet");
}
}
function foo() {
assumeMyConst();
// ...
}
但同样,请尽可能避免使用它。
旁注:请注意该async
IIFE中的错误检查。不要跳过错误检查。 :-)
答案 2 :(得分:1)
由于myConst
在async
代码完成后获得其值,因此它是Promise
类型的。因此,您的声明应该非常简单:
declare const myConst: Promise<any> // or type of the value instead of any
在任何地方使用它:
myConst.then((v) => console.log(v))
P.S。我的个人建议是尽可能使用模块(导入/导出)。全局变量是代码的味道。