我对Promises和async / await完全陌生,只是阅读了教程等内容,所以我希望我可能缺少一些基本知识。
我在几个地方都看到过这种代码模式,但是我想也许不应该相信它:
async function myFunc() {
try {
var result = await doSomethingAsync();
console.log(result);
}
catch(error) {
console.error(error); // hmm
}
}
myFunc();
使用上述模式考虑以下情形:
const doSomethingAsync = behaviour => new Promise((resolve, reject) => {
// use setTimeout to simulate e.g. an async webapi callback func
setTimeout(() => {
if(behaviour === "set resolve")
resolve("resolved");
if(behaviour === "set reject")
reject("rejected");
if(behaviour === "set after timeout error")
throw new Error("something went wrong after setTimeout returned");
}, 500);
if(behaviour === "set promise error")
throw new Error("something went wrong in promise");
});
async function myFunc(behaviour) {
try {
// wait for promise to complete
var result = await doSomethingAsync(behaviour);
console.log(result);
}
catch(error) {
console.error("caught:" + error); // will catch reject and promise error,
// but NOT after setTimeout error
}
}
myFunc("set promise error"); // caught:Error: something went wrong in promise
myFunc("set resolve"); // resolved
myFunc("set reject"); // caught:rejected
myFunc("set after timeout error"); // Uncaught Error: something went
// wrong after setTimeout returned
// UHOH!!
因此,该模式似乎有点误导,因为它无法捕获setTimeout错误,而人们倾向于将catch()视为全部捕获。
当然,将setTimeout更改为具有内部catch将解决未捕获的错误问题:
const doSomethingAsync = behaviour => new Promise((resolve, reject) => {
// use setTimeout to simulate e.g. an async webapi call
setTimeout(() => {
try { // ...
}
catch(e) { reject("an error"); }
}, 500);
});
所以,我的问题是:
据我所知,Promise用作回调的替代品,即用于包装诸如setTimeout之类的异步调用。那么,在Promise中是否应该始终有一个内部try / catch->拒绝模式? (以便调用者可以正常处理错误)。做例如所有节点库都以这种方式工作? 我看不到呼叫者自己可以处理的任何方式。
我发现该模式具有误导性,这样的模式会更好吗?
async function myFunc(behaviour) {
try {
var result = await doSomethingAsync(behaviour);
.catch(e) { console.log("expected reject happened:" + e) };
}
catch(error) {
console.error("something totally unexpected happened:" + error);
}
}