2017-01-23 31 views
1

两个try的打印Promise { <pending> }和第二个有Unhandled Promise Rejection Warning。我已经成功地使用Promises和.then和.catch,但是我想用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' 
    } 
} 

回答

13

使用asyncawait不会使你的整个程序异步。它使得特定功能异步。最后,async是一种语法糖,可以使编写承诺代码更容易。

一个async函数返回一个Promise。调用异步函数的代码必须将其视为返回承诺的函数。 (唯一的例外是当正在调用async函数的代码是本身在async功能,在这种情况下它可以是await编)

所以抛出Error被转换为一个Promise排斥反应。你不能在try..catch块中捕获它,原因很简单,因为try..catch在抛出错误之前已结束! (同样,例外情况是当你从async函数中调用它时,如果你是await的异步函数,try..catch块将会工作,在这种情况下,try..catch块被视为添加了Promise#catch函数。

你最终不得不使用正常Promise#catch法或与第二个参数Promise#then赶上从async函数错误:

getNewTokens('no-such-refresh-token', 1) 
    .then(function(tokens) { 
     console.log(tokens); 
    }, function(error) { 
     console.log(error.message); 
    }); 
0

在异步初学者实用的接听/等待和错误处理

不能使用等待语法不与异步宣布在它的面前,像这样功能之外......

async function myAsyncFunction() { 
    // code 
} 

所以,最后,你必须使用旧无极的方式来消耗声明为功能异步

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); 
    } 
}