Этот вопрос касается эмуляции поведения async
/ await
с использованием генераторов и обещаний, как описано здесь:
https://gist.github.com/ChrisChares/1ed079b9a6c9877ba4b43424139b166d
Вот минимальный пример, раскрывающий проблему:
Функция async
дословно взята по ссылке выше.
function async(gen, context = undefined) {
const generator = typeof gen === 'function' ? gen() : gen; // Create generator if necessary
const { value: promise } = generator.next(context); // Pass last result, get next Promise
if ( typeof promise !== 'undefined' ) {
promise.then(resolved => async(generator, resolved))
.catch(error => generator.throw(error)); // Defer to generator error handling
}
}
function timesTwoPlusOne(num){ //multiplies argument by 2 and adds one, asynchronously
return new Promise(function(resolve, reject) {
async(function*(){
//throw 'Fake exception 1' ;
num = yield Promise.resolve( 2*num ) ; //multiply by 2, asynchronously
//throw 'Fake exception 2' ;
resolve( num + 1 ) ; //add one, synchronously
}) ;
});
}
//run an asynchronous procedure
async(function*(){
let result ;
try{
result = yield timesTwoPlusOne(10) ;
}catch(e){
//the intention is to catch any exception happening inside `timesTwoPlusOne`
console.log('CATCHED:', e) ;
}
console.log( result ) ;
}) ;
Код как таковой работает нормально.Он печатает 21
, как и ожидалось.
Однако внутри функции timesTwoPlusOne
есть две закомментированные строки.
Когда мы раскомментируем первую (throw 'Fake exception 1'
) и пытаемся снова, это исключение распространяетсяи пойман единственным блоком catch
во всем коде.
Это именно то, что я хочу.Пока все хорошо.
Но теперь, если мы раскомментируем вторую строку (throw 'Fake exception 2'
) и оставим первую закомментированную, это исключение НЕ перехватывается.
Почему *Блок 1032 *, способный перехватить первое исключение, но не второе?