[英]Async await usage and error handling woes
Both try's print Promise { <pending> }
and the second one has an Unhandled Promise Rejection Warning
. 两个都尝试打印Promise { <pending> }
,第二个有Unhandled Promise Rejection Warning
。 I've had success just using Promises with .then and .catch, but there's some stuff I'd like to code in more of a synchronous way using async/await. 我已经成功使用了.then和.catch的Promises,但有些东西我想使用async / await以更多的同步方式进行编码。 Should I be using Yield instead perhaps? 我可能会使用Yield吗?
try {
var tokens = getNewTokens('refresh-token', 1)
console.log(tokens)
} catch (error) {
console.log(error.message)
}
try {
tokens = getNewTokens('no-such-refresh-token', 1)
console.log(tokens)
} catch (error) {
console.log(error.message)
}
function getRefreshToken (refreshToken, userId) {
return new Promise((resolve, reject) => {
if (refreshToken === 'refresh-token' && userId === 1) {
return resolve({
refreshToken: 'refresh-token',
accessToken: 'jwt'
})
} else {
const error = Error('Refresh token not found')
return reject(error)
}
})
}
async function getNewTokens (refreshToken, userId) {
if (!refreshToken || !userId) {
throw Error('Missing params')
}
try {
var result = await getRefreshToken(refreshToken, userId)
} catch (error) {
throw Error(error.message)
}
if (!result) {
throw Error('Something went bonk')
}
// Do stuff..
// get user from DB
// update refresh token with a new one
// make new jwt
return {
user: {
id: 1,
name: 'Jerry',
role: 'admin'
},
newRefreshToken: 'new-refresh-token',
newAccessToken: 'new-jwt'
}
}
Using async
and await
does not make your whole program asynchronous. 使用async
和await
不会使整个程序异步。 It makes particular functions asynchronous. 它使特定函数异步。 In the end, async
is syntactical sugar that makes writing promise code easier. 最后, async
是语法糖,使得编写承诺代码更容易。
An async
function returns a Promise
. async
函数返回Promise
。 The code that calls the asynchronous function must treat it as a function that returns a promise. 调用异步函数的代码必须将其视为返回promise的函数。 (The only exception is when the code that is calling the async
function is itself in an async
function, in which case it can be await
ed.) (唯一的例外是当调用async
函数的代码本身在async
函数中时,在这种情况下可以await
编辑。)
So throwing an Error
gets translated into a Promise
rejection. 因此抛出一个Error
会被转化为Promise
拒绝。 You can't catch it in a try..catch
block for the simple reason that the try..catch
is over way before the error is thrown! 您无法在try..catch
块中捕获它,原因很简单, try..catch
在抛出错误之前try..catch
经过了! (Again, the exception is when you're calling it from an async
function. If you are await
ing an asynchronous function, a try..catch
block will work. In this case the try..catch
block is treated as if it were adding a Promise#catch
function.) (同样,例外情况是当你从async
函数调用它时。如果await
异步函数, try..catch
块将起作用。在这种情况下, try..catch
块被视为是添加一个Promise#catch
函数。)
You ultimately have to catch errors from an async
function using the normal Promise#catch
method or with the second argument to Promise#then
: 您最终必须使用正常的Promise#catch
方法或使用Promise#then
的第二个参数从async
函数中捕获错误:
getNewTokens('no-such-refresh-token', 1)
.then(function(tokens) {
console.log(tokens);
}, function(error) {
console.log(error.message);
});
I would like to submit this as a reasonable and readable way to handle errors using async/await. 我想提交这个作为使用async / await处理错误的合理且可读的方法。
const value = await asyncFunction().catch(err => new Error(err))
if (value instanceof Error) return res.status(500).send('There was an error doing something')
By adding the .catch()
method, which returns an Error
, thus assigning it to the value
variable , we can be sure that some value will be present in our variable. 通过添加返回 Error
的.catch()
方法, 从而将其赋值给 value
变量 ,我们可以确定变量中会出现一些值。 The only additional line of code necessary is the if
statement to test if the value is an instance of Error
. 唯一需要的额外代码行是if
语句来测试该值是否为Error
的实例。 If it was caught for any reason, it will definitely be an instanceof Error (our code makes sure of that), and our program can safely handle that scenario (in the above case we are returning 500 as a server response, thus preventing the program from executing any dangerous code as a result of the error in the asyncFunction). 如果它因任何原因被捕获,它肯定会是一个错误的实例(我们的代码确保这一点),并且我们的程序可以安全地处理该场景(在上面的例子中,我们返回500作为服务器响应,从而阻止程序由于asyncFunction中的错误而执行任何危险代码)。
I intentionally wrote this in 2 lines to highlight the fact that this can be written tersely and avoid the use of try
/ catch
blocks, which many do not enjoy reading (myself being one). 我故意用2行写这个,以突出这个事实,这可以简洁地写,避免使用try
/ catch
块,许多人不喜欢阅读(我自己就是一个)。
If you're cool with reading try
/ catch
blocks, congratulations. 如果你对阅读try
/ catch
块很酷,恭喜你。 I just find it makes the code look janky. 我发现它使代码看起来很笨拙。 Oh well. 那好吧。 ¯\\_(ツ)_/¯
You cannot use await syntax outside of a function that is not declared with async or is a promise. 您不能在未使用async声明的函数之外使用await语法,也不能使用promise。
async function myAsyncFunction() {
// code
}
or 要么
const myPromiseFunction = () => new Promise((resolve, reject) => {
// code
})
So ultimately, you have to use the old Promise way to consume a function declared as async 所以最终,你必须使用旧的Promise方法来使用声明为async的函数
myAsyncFunction().then(() => console.log('here'));
because both are Promises. 因为两者都是承诺。
Now to actually handle errors like you are used to in the then - catch way, you have to construct your async function like so... 我们真正处理的错误你是在当时的使用- 捕捞方式,你必须构建你的异步函数是这样的...
async function getUser(username) {
return await db.users.get({ username });
}
then you can use this like a normal Promise outside of an async method like so... 然后你就可以像异步方法一样使用它像普通的Promise一样......
getUser()
.then(user => console.log(user))
.catch(err => console.error(err));
or you guessed it, use it within an async function using await. 或者你猜对了,使用await在异步函数中使用它。
async function getJoffery() {
return await getUser('joffery');
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.