首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在可达性分析中不考虑Promise<never>?

为什么在可达性分析中不考虑Promise<never>?
EN

Stack Overflow用户
提问于 2019-11-06 14:51:40
回答 1查看 621关注 0票数 17

假设我们有这样的功能:

代码语言:javascript
复制
function returnNever(): never {
    throw new Error();
}

当创建生命时,它之后出现的代码被标记为不可访问的代码:

代码语言:javascript
复制
(async () => {
    let b: string;
    let a0 = returnNever();
    b = ""; // Unreachable
    b.toUpperCase(); // Unreachable
})();

这如预期的那样起作用。注意,a0被推断为never类型。

但是,如果returnNever()返回一个Promise<never>并得到等待,则行为是不同的:

代码语言:javascript
复制
(async () => {
    let b: string;
    let a1 = await Promise.reject(); // returns Promise<never>
    b = ""; // Not unreachable?
    b.toUpperCase(); // Not unreachable?
})();

在这种情况下,a1也被推断为never类型。但是之后的代码并没有被标记为不可访问。为什么?

背景:我最近偶然发现了一些类似于以下代码的logError函数。它在catch块中使用。通过这种方式,我发现,不是可达性分析,而是明确的分配分析受以下因素的影响:

代码语言:javascript
复制
declare function fetchB(): Promise<string>;
async function logError(err: any): Promise<never> {
    await fetch("/foo/...");
    throw new Error(err);
}
(async () => {
    let b: string;
    try {
        b = await fetchB(); // Promise<string>
    } catch (err) {
        await logError(err); // awaiting Promise<never>
    }
    b.toUpperCase(); // Error: "b" is used before assignment
})();

如果logError是同步的(通过删除与logError相关的所有awaitasyncs ),则不会出现错误。另外,如果将let b: string更改为let b: string | undefined,则在try-catch块之后不会删除undefined

在控制流分析的任何方面,似乎都有理由不考虑awaitPromise<never>-returning函数。这也可能是一个bug,但我更愿意在这里忽略一些细节。

EN

回答 1

Stack Overflow用户

发布于 2022-10-14 02:37:02

从技术上讲,承诺是异步进程,这意味着在对承诺本身进行评估时,承诺之后的代码将继续运行。因此,即使承诺最终因错误而终止,仍然有可能在仍在对其进行评估时达到它之后的代码。这可能是为什么代码没有标记为不可访问的原因,尽管在现实中,将后面的任何代码视为不可访问的代码是有意义的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58732814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档