是否有更简洁的方法来获取错误和 Promise 的结果 [重复]

Posted

技术标签:

【中文标题】是否有更简洁的方法来获取错误和 Promise 的结果 [重复]【英文标题】:Is there a cleaner way of getting error and result of a Promise [duplicate] 【发布时间】:2021-08-05 00:59:05 【问题描述】:

我想知道如果没有异步函数内部的 try/catch 块,我们是否可以得到错误和 Promise 的结果。

(async function()
    let  user, error  = await getUser();
    .
    .
    .
     user, error  = await user.save();
)();

在不使用 try/catch 块或 .then().catch() 的情况下,有没有更简洁的 Promises 错误处理方式?

【问题讨论】:

错误没有得到解决,它被拒绝了。所以不,试试 catch 或 .catch。 @jonrsharpe 好的,感谢您的回答。请让我根据您的评论添加另一个问题。考虑到我有几个设置为等待的 Promise,它们都执行不同的任务。如果我将它们全部放在 try/catch 块中,我该如何处理错误?我的意思是我怎么知道哪个是抛出错误?如果我对所有这些都使用 .catch() ,我如何回调将错误返回到主异步函数?我需要使用回调吗? 如果你想知道哪一个出错了,你不要把它们都放在同一个try块中。 你有Promise.all, Promise.allSettled, Promise.any, and Promise.race 以干净的方式聚合多个待处理的承诺。 你实际上并不想要承诺的错误和结果,it's not cleaner。 【参考方案1】:

这怎么比这更干净?

async function updateUser() 
    const user = await getUser();
    .
    .
    .
    const result = await user.save();
    return result;
    // or
    // return user.save();

如果出错,updateUser() 的调用者知道 if 它应该处理它以及 what 它应该做什么。如果调用者不知道要做什么,那么调用者也将返回一个承诺(通过asyncawait 调用updateUser() 或通过返回updateUser() 返回的承诺) , 而且它不需要执行错误处理

最终,您将到达调用堆栈中的一个框架,该框架知道如何处理错误,在这种情况下,它会对等待的任何可能被拒绝的 Promise 执行错误处理。如果没有,那么您可能已经从框架或程序的入口点到达回调,这可能会将错误作为未处理的承诺拒绝传播。

在promise之前,有callbacks,不写这样的东西需要很多纪律:

function updateUser(callback) 
    getUser(function (error, user) 
        if (error) 
            return callback(error);
        

        user.save(function (error, result) 
            if (error) 
                return callback(error);
            

            callback(null, result);
            // or
            // callback(error, result);
        );
        // or
        // user.save(callback);
    );

请注意,即使是不知道如何处理错误的回调也必须显式地执行错误处理无论如何,这就是 promise 如此糟糕的原因之一。有人可能会指出,您可以通过将每个回调提取到一个命名函数中以在视觉上展平递归来使其更清晰,但即便如此,每个回调仍然必须执行错误处理。

然后promise出现了,每帧显式错误处理的问题最终消失了:

function updateUser() 
    return getUser().then(user => 
        return user.save();
    ).then(result => 
        return result;
    );
    // exposition only

【讨论】:

非常感谢。你的回答对我的问题很有帮助。我对你的例子有 3 个问题。 1) 在第一个代码块中,您没有使用 try/catch 进行错误处理。那是故意的吗?我的意思是它会直接抛出一个 UnhandledPromiseRejection 我猜。 2)在你的第三个代码块中,我们需要做的就是在链中添加一个 .catch() 来处理所有可能发生的错误,对吧? 3)我无法理解您在第三个代码块中的“仅展示”是什么意思。请解释一下好吗? @M.ÇağlarTUFAN 1) 是的,这是故意的。答案的重点是表明async / await 提供了最少的样板因为您不会将错误作为API 的一部分。结果和错误保存在完全独立的控制流中。 2) 与第一个代码块的解释类似,您不需要添加.catch() 块,除非updateUser() 知道如何处理错误。 3)这只是意味着.then(result => return result; ); 是完全多余的,只是显示result 去了哪里。您可以删除它,它仍然可以正常工作。 哦,我明白了。感谢您的回答。我会尽力练习这些基础知识。祝你有美好的一天!

以上是关于是否有更简洁的方法来获取错误和 Promise 的结果 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

c# - 是不是有更简洁的方法来检查变量是不是是多个事物之一?

Python 是不是有更简洁的方式来表达“如果 x 包含 a|b|c|d...”? [复制]

是否有更简单或单行的方法来获取 DataGridViewComboBoxCell 的选定索引?

是否有更简单的方法来获取张量的切片,如下例所示?

如果数组为空则跳过foreach的最简洁方法[重复]

有没有更简洁的方法来编写这个轮询循环?