Typescript 如何避免;“承诺中的非预期错误”;使用异步/等待
以下代码是我的问题的MCVE:Typescript 如何避免;“承诺中的非预期错误”;使用异步/等待,typescript,promise,async-await,Typescript,Promise,Async Await,以下代码是我的问题的MCVE: class MyApp { public async crash(): Promise<number> { throw new Error("Hello Error"); } public async chain(promise: Promise<number>) { await this.delay(10000); return promise; }
class MyApp {
public async crash(): Promise<number> {
throw new Error("Hello Error");
}
public async chain(promise: Promise<number>) {
await this.delay(10000);
return promise;
}
private async delay(ms: number): Promise<void> {
return new Promise<void>( resolve => setTimeout(resolve, ms) );
}
}
const myApp = new MyApp();
const a = async () => {
try {
const foo = await myApp.chain(myApp.crash());
} catch (e) {
console.log("Hello Catch");
}
};
a();
如果要执行的任务崩溃的速度超过我显示微调器的速度,我的整个应用程序都会崩溃。在你跳进去告诉我添加一个挡块之前,请看MCVE,这不是问题所在。我确实从调用链更高的
await
捕捉到了异常,但崩溃发生在代码到达await
之前。问题是,您正在构建一个承诺,而没有对它做任何事情(没有安装错误处理程序!),同时在等待其他承诺:
let promise = crash();
await loadingSpinner.present();
await promise;
这是一个众所周知的反模式:
一般来说,您的方法应该接受值而不是承诺,但是在这种情况下,如果您想要包装承诺,那么它可能是有保证的。但你仍然需要立即处理它。正确的解决办法是
public async showWait<T>(promise: Promise<T>): Promise<T> {
try {
const [, val] = await Promise.all([
loadingSpinner.present(),
promise,
]);
return val;
} finally {
await loadingSpinner.dismiss();
}
}
公共异步showWait(promise:promise):promise{
试一试{
常数,常数等待承诺([
loadingSpinner.present(),
承诺,,
]);
返回val;
}最后{
等待loadingSpinner.Disclose();
}
}
问题在于,在等待其他承诺的同时,您正在构建一个承诺,而没有对它做任何事情(没有安装错误处理程序!):
let promise = crash();
await loadingSpinner.present();
await promise;
这是一个众所周知的反模式:
一般来说,您的方法应该接受值而不是承诺,但是在这种情况下,如果您想要包装承诺,那么它可能是有保证的。但你仍然需要立即处理它。正确的解决办法是
public async showWait<T>(promise: Promise<T>): Promise<T> {
try {
const [, val] = await Promise.all([
loadingSpinner.present(),
promise,
]);
return val;
} finally {
await loadingSpinner.dismiss();
}
}
公共异步showWait(promise:promise):promise{
试一试{
常数,常数等待承诺([
loadingSpinner.present(),
承诺,,
]);
返回val;
}最后{
等待loadingSpinner.Disclose();
}
}
谢谢。我来自C#,在C#中,这不是一个反模式,因为任务不关心处理程序,如果它认为有必要,等待将抛出。我读的教程使用了相同的模式,所以我没有真正考虑:(我想我需要更新我的google-a-good-tutorial技能:)@nvoigt你是对的,不幸的是,这不是很清楚。JS确实有一个未经处理的拒绝警告,这样您就不会轻易错过错误,但当您希望遵守被拒绝的承诺,并且只在以后处理时,它会成为一个障碍。不过你可以,谢谢你。我来自C#,在C#中,这不是一个反模式,因为任务不关心处理程序,如果它认为有必要,等待将抛出。我读的教程使用了相同的模式,所以我没有真正考虑:(我想我需要更新我的google-a-good-tutorial技能:)@nvoigt你是对的,不幸的是,这不是很清楚。JS确实有一个未经处理的拒绝警告,这样您就不会轻易错过错误,但当您希望遵守被拒绝的承诺,并且只在以后处理时,它会成为一个障碍。不过你可以。