我喜欢在Typescript等中提供的新Async/Await
功能的平坦性。但是,我不确定我喜欢我必须声明变量我await
的事实try...catch
块的外部,以便稍后使用它。像这样:
let createdUser
try {
createdUser = await this.User.create(userInfo)
} catch (error) {
console.error(error)
}
console.log(createdUser)
// business
// logic
// goes
// here
如果我错了,请纠正我,但在try
正文中放置多行业务逻辑似乎是不的最佳做法,所以我只留下了在块外声明createdUser
的替代方法,在块中指定它,然后在之后使用它。
在这种情况下,最佳做法是什么?
答案 0 :(得分:28)
似乎最好不要在try主体中放置多行业务逻辑
其实我说的是。您通常希望使用以下值catch
所有例外:
try {
const createdUser = await this.User.create(userInfo);
console.log(createdUser)
// business logic goes here
} catch (error) {
console.error(error) // from creation or business logic
}
如果您只想从承诺中捕获和处理错误,您有三种选择:
将变量声明为外部,并根据是否存在异常进行分支。这可以采取各种形式,如
catch
块return
提前或重新throw
来自catch
区块的例外catch
块是否捕获了异常,并在if
条件下对其进行测试
let createdUser; // or use `var` inside the block
try {
createdUser = await this.User.create(userInfo);
} catch (error) {
console.error(error) // from creation
}
if (createdUser) { // user was successfully created
console.log(createdUser)
// business logic goes here
}
测试捕获的异常的类型,并根据它处理或重新抛出它。
try {
const createdUser = await this.User.create(userInfo);
// user was successfully created
console.log(createdUser)
// business logic goes here
} catch (error) {
if (error instanceof CreationError) {
console.error(error) // from creation
} else {
throw error;
}
}
不幸的是,标准JavaScript(仍然)没有conditional exceptions的语法支持。
使用then
with two callbacks代替try
/ catch
。这实际上是最不丑陋的方式,也是我个人的建议,因为它的简单性和正确性,不依赖于标记的错误或结果值的外观来区分履行的履行和拒绝:
await this.User.create(userInfo).then(createdUser => {
// user was successfully created
console.log(createdUser)
// business logic goes here
}, error => {
console.error(error) // from creation
});
当然它带有引入回调函数的缺点,这意味着你不能轻易地break
/ continue
循环或从外部函数做早期return
。
答案 1 :(得分:4)
另一种更简单的方法是将.catch追加到promise函数。例如:
const createdUser = await this.User.create(userInfo).catch( error => {
// handle error
})
答案 2 :(得分:0)
@Bergi答案很好,但是我认为这不是最好的方法,因为您必须回到旧的then()方法,所以我认为更好的方法是捕获异步函数中的错误
async function someAsyncFunction(){
const createdUser = await this.User.create(userInfo);
console.log(createdUser)
}
someAsyncFunction().catch(console.log);
await
并且需要捕获每个错误怎么办?您可以声明to()
函数
function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]);
}
然后
async function someAsyncFunction(){
let err, createdUser, anotherUser;
[err, createdUser] = await to(this.User.create(userInfo));
if (err) console.log(`Error is ${err}`);
else console.log(`createdUser is ${createdUser}`);
[err, anotherUser] = await to(this.User.create(anotherUserInfo));
if (err) console.log(`Error is ${err}`);
else console.log(`anotherUser is ${anotherUser}`);
}
someAsyncFunction();
在阅读此内容时:“等待this.User.create”。
最后,您可以创建模块“ to.js”或直接使用await-to-js模块。
您可以在this post中获得有关to
函数的更多信息
答案 3 :(得分:0)
我通常在失败时使用Promise的catch()
函数返回具有error
属性的对象。
例如,在您的情况下,我会这样做:
const createdUser = await this.User.create(userInfo)
.catch(error => { error }); // <--- the added catch
if (Object(createdUser).error) {
console.error(error)
}
如果您不想继续添加catch()
调用,则可以在该函数的原型中添加一个辅助函数:
Function.prototype.withCatcher = function withCatcher() {
const result = this.apply(this, arguments);
if (!Object(result).catch) {
throw `${this.name}() must return a Promise when using withCatcher()`;
}
return result.catch(error => ({ error }));
};
现在您可以:
const createdUser = await this.User.create.withCatcher(userInfo);
if (Object(result).error) {
console.error(result);
}