等待/异步如何处理未解决的承诺 [英] await/async how to handle unresolved promises

查看:51
本文介绍了等待/异步如何处理未解决的承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您如何处理未解决的承诺?

How do you handle promises that do not resolve?

示例:

class Utils {
    static async thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(number: number) {
        return new Promise((resolve, reject) => {
            if(number === 2) {
                resolve('ok')
            }
        })
    }
}

console.log(await Utils.thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(2))
// this will print "ok" because 2 is passed and the promise is resolved

console.log(await Utils.thisFunctionOnlyResolvesWhenPassed2AndNeverRejects(5))
// this will crash the program silently 

uncaughtExceptionunhandledRejection 在 promise 未解析时不返回任何内容.在 await 周围添加 try/catch 不起作用(没有错误).最后,唯一有效的是使用 Promise.then 而不是 await.

uncaughtException and unhandledRejection return nothing when the promise is unresolved. Adding a try/catch around the await doesn't work (no errors). Finally, the only thing that works is using Promise.then instead of await.

问题是代码库充满了 async/await 和有时会解决的承诺(取决于条件)

Problem is the code base is riddled with async/await and Promises that sometimes resolve (depending on conditions)

问题:是否可以添加打字稿标志来检测丢失的解析/拒绝?或者可能是一种将所有 async/await 转译为使用 Promise.then 的自动方法?

Question: Is there a typescript flag I can add to detect a missing resolve/reject? or maybe an automated way to transpile all the async/await to use Promise.then?

使用调试器时,程序在 Promise 之后停止,很难找到哪个函数/promise 缺少 resolve/reject.

When using a debugger, the program stops after the Promise and it is difficult to find which function/promise has a missing resolve/reject.

重写所有 async/await 调用以使用 Promise.then 是我最后的手段.

Rewriting all the async/await calls to use Promise.then is my last resort.

推荐答案

如果您的承诺偶尔无法解决或拒绝,并且这不是他们应该工作的方式(通常不是),那么您只需要解决这个问题.真的没有解决方法.正确的解决方法是深入到最低级别并修复代码,使其每次都能可靠地解决或拒绝.

If you have promises that occasionally don't resolve or reject and that's not the way they are supposed to work (which it usually isn't), then you just have to fix that. There really is no work-around. The proper fix is to get down to the lowest level and fix the code so it reliably resolves or rejects every time.

这不是正确的解决方法,但实现超时包装器可以帮助调试,为您提供一条日志消息,其中包含一些类似于超时承诺的堆栈跟踪:

This is not the proper fix, but implementing a timeout wrapper could help with debugging giving you a log message with some semblance of a stack trace for a timed out promise:

function rejectT(t) {
    // create potential error here for better opportunity at stack trace
    let e = new Error("Promise timed out");
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(e);
            reject(e);
        }, t);
    });
}

function timeout(p, t = 5000) {
    return Promise.race([p, rejectT(t)]);
}

然后你可以包装任何承诺,而不是:

You can then wrap any promise such that instead of:

fn().then(...).catch(...)

您可以使用:

timeout(fn()).then(...).catch(...);

或者,如果您想设置自定义超时值:

Or, if you want to set a custom timeout value:

timeout(fn(), 1000).then(...).catch(...);

同样,这是调试代码以帮助找到需要修复的罪魁祸首并帮助测试修复,而不是包扎您的代码.

Again, this is debugging code to help find the culprits that need fixing and to help test fixes, not to bandaid your code.

重写所有 async/await 调用以使用 Promise.then 是我最后的手段.

Rewriting all the async/await calls to use Promise.then is my last resort.

我根本看不出这会有什么帮助.如果 await 永远不会结束,promise.then() 也不会结束.他们在这方面完全相同.如果承诺永远不会解决或拒绝,那么 .then() 处理程序也永远不会被调用.

I don't see how this is going to help at all. If await never finishes, neither will promise.then(). They are exactly the same in that regard. If the promise never resolves or rejects, then the .then() handler will never get called either.

问题是代码库充满了 async/await 和有时会解决的 Promises(取决于条件)

Problem is the code base is riddled with async/await and Promises that sometimes resolve (depending on conditions)

除了有条不紊的代码审查之外,这里没有其他捷径,可以找到具有永远无法解析或拒绝的代码路径的可疑代码,然后构建单元测试来测试在各种条件下返回承诺的每个函数.

There's no shortcut here other than methodical code review to find suspect code that has code paths that may never resolve or reject and then building unit tests to test every function that returns a promise in a variety of conditions.

从不解析或拒绝的一个可能的代码来源是一些承诺反模式.其中一些是反模式的确切原因是因为它们很容易搞砸.以下是一些可能会提高您对可疑代码的敏感性的参考资料:

One likely source of code that never resolves or rejects are some of the promise anti-patterns. The precise reason some of them are anti-patterns is because they can be very easy to mess up. Here are a few references that might spike your sensitivity to suspect code:

承诺反模式

常见的 Promise 反模式和方法避开它们

ES6 承诺:模式和反模式

这篇关于等待/异步如何处理未解决的承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆