2017-01-23 62 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); 
    } 
}