两个尝试打印Promise { <pending> }
和第二个有Unhandled Promise Rejection Warning
。我已经成功使用了.then和.catch的Promises,但有些东西我想使用async / await以更多的同步方式进行编码。我可能会使用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'
}
}
使用async
和await
不会使整个程序异步。它使特定函数异步。最后,async
是语法糖,使编写承诺代码更容易。
async
函数返回Promise
。调用异步函数的代码必须将其视为返回promise的函数。 (唯一的例外是当调用async
函数的代码本身在async
函数中时,在这种情况下它可以是await
ed。)
所以投掷一个Error
被转换成Promise
拒绝。你不能在try..catch
区块中捕获它,原因很简单,因为在抛出错误之前try..catch
已经过了! (同样,例外情况是你从async
函数调用它。如果你是await
ing异步函数,try..catch
块将工作。在这种情况下,try..catch
块被视为添加了Promise#catch
函数。)
你最终必须使用正常的async
方法或Promise#catch
的第二个参数从Promise#then
函数中捕获错误:
getNewTokens('no-such-refresh-token', 1)
.then(function(tokens) {
console.log(tokens);
}, function(error) {
console.log(error.message);
});
我想提交这个作为使用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')
通过添加返回.catch()
的Error
方法,从而将其赋值给value
变量,我们可以确定我们的变量中会出现一些值。唯一需要的额外代码行是if
语句来测试该值是否为Error
的实例。如果它因任何原因被捕获,它肯定会是一个错误的实例(我们的代码确保这一点),并且我们的程序可以安全地处理该场景(在上面的例子中,我们返回500作为服务器响应,从而阻止程序由于asyncFunction中的错误而执行任何危险代码)。
我有意写了两行,以突出这一事实,这可以简洁地写,避免使用try
/ catch
块,许多人不喜欢阅读(我自己就是一个)。
如果你阅读try
/ catch
积木很酷,恭喜你。我发现它使代码看起来很笨拙。那好吧。 ¯\_(ツ)_/¯
你不能在未使用async声明的函数之外使用await语法,就像这样......
async function myAsyncFunction() {
// code
}
所以最终,你必须使用旧的Promise方法来使用声明为async的函数
myAsyncFunction().then(() => console.log('here'));
因为它是一种承诺。
现在要实际处理像你习惯的那样的错误,你必须构建你的异步函数,就像这样......
async function getUser(username) {
try {
return await db.users.get({ username });
} catch (err) {
return Promise.reject(err);
}
}
然后你可以像在异步方法之外的普通Promise一样使用它...
getUser()
.then(user => console.log(user))
.catch(err => console.error(err));
或者你猜对了,使用await在异步函数中使用它。
async function getJoffery() {
try {
return await getUser('joffery');
} catch (err) {
return Promise.reject(err);
}
}