Accidentally see the following this problem, is to investigate async… Await mechanism, WHICH I find interesting. You can try to mentally calculate the results without using the console.

const Err = async() = > {throw new Error(42);
};

const Obj = {
	async A (){
		try {
			return Err();
		} catch {
			console.log('A'); }},async B (){
		try {
			await Err();
		} catch {
			console.log('B'); }},async C (){
		try {
			Err();
		} catch {
			console.log('C'); }}}; (async() = > {for( const key in Obj )
	{
		try {
			await Obj[key]();
		} catch {
			console.log('D'); }}}) ();Copy the code

Put a picture in case you see the answer

A. Uncaught (in promise) Error: 42 b. Uncaught (in promise) Error: 42

In summary, this question mainly examines the following knowledge points:

asyncThe function always returns a promise

What is this promise? It can be divided into the following situations:

  1. If the body of a function throws an error, the function executes with the errorPromise.reject()Packaging object
  2. If the body of the function returns a promise, the result of the function execution is the promise.
  3. Otherwise, the result of function execution is the return value of the function bodyPromise.resolve()Wrap objects. One situation that can be confusing is the body of a functionreturn new Erro(1), the execution result is equivalent toPromise.resolve(new Error(1)), pay attention toreturn new Error(1)andthrow new Error(1)The difference between.
async function fn1() {
    throw new Error(1)
}
async function fn2() {
    return Promise.reject(1)
}
async function fn3() {}
async function fn4() {
    return new Error(1)
}
fn1()   // Promise {<rejected>: Error: 1}
fn2()   // Promise {<rejected>: 1}
fn3()   // Promise {<fulfilled>: undefined}
fn4()   // Promise {<fulfilled>: Error: 1}
Copy the code

awaitWaiting to unlock a promise, waiting for an error

The above title is for brevity and may not be very accurate, but I will break it down into several points:

  1. awaitAlways followed by a promise, and if it’s not followed by a promise, yesPromise.resolve()Wrap it up.
  2. ifawaitThe expression is followed byfulfilledState promise, returns the corresponding value.
  3. ifawaitThe expression is followed byrejectedState promise, which throws an error, can be usedThe catch () methodortry... catchPiece of capture.
async function fn1() {
    const res = await Promise.resolve(1)
    console.log(res)
}
async function fn2() {
    const res = await new Error(1) // Equivalent to promise.resolve (new Error(1))
    console.log(res)
}
async function fn3() {
    const res = await Promise.reject(1)
    console.log(res)    
}
fn1()   / / 1
fn2()   // Error: 1
fn3()   Uncaught (in promise) 1
// Fn3 can be rewritten in either form to catch errors
async function fn3() {
    const res = await Promise.reject(1).catch(e= > {
        console.log(e)
    })
}
async function fn3() {
    try {
        const res = await Promise.reject(1)}catch(e) {
        console.log(e)
    }
}
Copy the code

With that in mind, we’re ready to analyze the code. I’ve put the explanation in the code comment below, so it should look a little clearer:

const Err = async() = > {throw new Error(42);
	// Equivalent to return promise.reject (new Error(42))
};

const Obj = {
	async A (){
	    // 1.2 in the for loop 'await A()' is equivalent to 'await promise.reject (new Error(42))'
	    // will be caught by the catch block inside the for loop
	    // ** so the first round of the for loop outputs D**
		try {
			return Err();
			// 1.1 equals return promise.reject (new Error(42))
			// This line of code does not throw an error, so the following catch block will not walk and will not print A
		} catch {
			console.log('A'); }},async B (){
	    // 2.2 in the for loop 'await B()' is equivalent to 'await promise.resolve (undefined)'
	    // This line of code is not caught by the catch block inside the for loop
	    // ** so the second round of the for loop outputs B**
		try {
		    // 2.1 is equivalent to 'await promise.reject (new Error(42))'
		    // This line of code is caught by the following catch block, printing B
			await Err();
		} catch {
			console.log('B'); }},async C (){
	    // 3.2 'await C()' in the for loop is equivalent to 'await promise.resolve (undefined)'
	    // Will not be caught by the catch block inside the for loop
	    // ** so in round 3 nothing is output. Uncaught (in promise) Error: 42 **
		try {
		    // 3.1 is equivalent to 'promise.reject (new Error(42))'
		    // This line of code will not be caught by the following catch block and will not print C
		    // If the 'rejected' promise is not handled by catch, it will report 'Uncaught (in promise) Error: 42'
		    / / note that try... 'promise.reject ()' is not the same as' await promise.reject () 'in a catch block.
			Err();
		} catch {
			console.log('C'); }}}; (async() = > {for( const key in Obj )
	{
		try {
			await Obj[key]();
		} catch {
			console.log('D'); }}}) ();Copy the code