【问题标题】:Typescript: Need to declare a const in the global scope reading from asynchronous function打字稿:需要在从异步函数读取的全局范围内声明一个常量
【发布时间】:2019-03-20 01:38:03
【问题描述】:

这里有一个新手问题。我需要在我的 Typescript 文件的顶层声明 const,以便下面的所有函数都可以访问它。问题是我需要分配给这个常量的值被异步函数返回,这就是我卡住的地方。无法从顶层调用异步函数 - 我可以这样做,但在这种情况下,常量不再位于顶层,其他函数无法访问。

(async () => {
    const myConst = await asyncFunction(params);
})(); 

另一种选择是使用 let 而不是 const,就像这样,但我宁愿在上面放 const

let myConst;
(async () => {
    myConst = await asyncFunction(params);
})();

你能给我建议吗?有什么办法可以让我为全局范围声明 const 并根据 async 函数为其分配一个值?

非常感谢:)

【问题讨论】:

  • 一般你想做的并没有真正的用处,因为全局变量只有在异步操作完成后才可用。
  • 这是设计使然。您不应该以这种方式混合同步和异步代码。如果您将来需要该变量,您可以使用 Promise 来描述它,而您通常这样做的方式是使用 async 函数。这样您就可以在值上await 以确保它存在(与您当前的方法相反,您只能猜测或轮询)
  • 要么使用承诺,要么将需要该常量的代码专门包装在异步块中。据我所知,这是有意设计的。

标签: javascript typescript asynchronous scope constants


【解决方案1】:

由于myConstasync 代码完成后获取它的值,它是Promise 类型。因此,您的声明应该非常简单:

declare const myConst: Promise<any> // or type of the value instead of any

像这样在任何地方使用它:

myConst.then((v) => console.log(v))

附:我个人的建议是尽可能使用模块(导入/导出)。全局变量是一种代码味道。

【讨论】:

  • 那里有三分之一的好答案。你能完成吗?解释为什么要为此使用 Promise,它解决了什么问题,以及依赖信息的函数将如何使用该 Promise? 编辑:Jesse Hallett 发布了此方法的完整版本。
  • 好的,我会写完的,对不起
【解决方案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 中的错误检查。不要跳过错误检查。 :-)

【讨论】:

    【解决方案3】:

    在顶级变量中使用异步结果是有问题的,因为当模块中的函数尝试读取值时,无法静态保证结果会准备就绪。在我看来,正确且安全的方法是将承诺分配给顶级变量,并使任何读取值 await 的函数成为结果:

    const myConst = asyncFunction(params);
    
    async function example() {
      doStuff(await myConst);
    }
    

    但是,如果将异步结果放在顶级变量中很重要,并且您有一些方法可以保证该值在读取之前准备好,那么我将使用您的 let 分配。在这种情况下,我认为没有任何好方法可以将该变量设为 const

    【讨论】:

    猜你喜欢
    • 2016-05-17
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 2017-10-22
    相关资源
    最近更新 更多