2017-01-23 2 views
1

Печать обеих попыток Promise { <pending> }, а вторая - Unhandled Promise Rejection Warning. У меня был успех, просто используя Promises с .then и .catch, но есть некоторые вещи, которые я хотел бы кодировать более синхронно, используя async/wait. Должен ли я использовать Yield вместо этого?Async ожидает использования ошибок и ошибок обработки ошибок

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

Использование async и await не делает всю программу асинхронно. Он делает определенные функции асинхронный. В конце концов, async является синтаксическим сахаром, который упрощает кодекс написания обещаний.

async функция возвращает Promise. Код, вызывающий асинхронную функцию, должен рассматривать его как функцию, которая возвращает обещание. (Единственное исключение, когда код, который вызов функции async сами в async функции, в этом случае он может быть await ред.)

Так выбрасывания Error переводятся в Promise отказ. Вы не можете поймать его в блоке try..catch по той простой причине, что try..catch закончил путь до появления ошибки! (Опять же, исключение - это когда вы вызываете его из функции async.Если вы используете await с асинхронной функцией, будет работать блок 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); 
    }); 
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); 
    } 
}