使用生成器和Promise时传播异常

时间:2018-09-13 21:12:38

标签: javascript ecmascript-6 exception-handling promise generator

这个问题是关于使用生成器和Promise模拟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')并保留第一行的注释,则不会捕获该异常。

为什么try/catch块能够捕获第一个异常,但不能捕获第二个异常?

0 个答案:

没有答案