Javascript错误写法

错误写法1:使用catch捕获非await方式调用的async函数中抛出的Error:

async function func() {
	throw new Error('error');
}

try {
    func();
} catch(e) {
    console.error(e.message);
}

导致后果1:未能捕获Error,且产生未处理promise rejection:

出错原因1:根据"Async function will return a Promise which will be rejected with an exception thrown from, or uncaught within, the async function",throw抛出Error使得func返回Promise { <rejected> Error: error },未处理Promise { <rejected> Error: error }导致UnhandledPromiseRejectionWarning。

async function func() {
	throw new Error('error');
}

console.log(func());

正确写法1.1: 在可能抛出Error的函数内使用 try/catch 结构:

async function func() {
    try {
        throw new Error('error');
    } catch(e) {
        console.error(e.message);
    }
}

func();

运行结果1.1:

正确写法1.2:在调用可能抛出Error的函数的末尾链接.catch() 块:

async function func() {
    throw new Error('error');
}

func()
.catch(e => {
	console.error(e.message);
});

运行结果1.2:

正确写法1.3:以await方式调用可能抛出Error的函数:

async function func() {
	throw new Error('error');
}

(async function() {
	try {
	    await func();
	} catch(e) {
	    console.error(e.message);
	}
})();

运行结果1.3: 

错误写法2:使用catch处理非await方式调用的async函数中返回的promise rejection:

async function func() {
    return await Promise.reject('reason');
}

try {
    func();
} catch(e) {
    console.error(e);
}

导致后果2:未能处理promise rejection:

出错原因2:

  1. func异步非阻塞执行立即返回Promise { <pending> };
  2. 随后Promise { <pending> }异步返回生成Promise { <rejected> 'reason' };
  3. catch无法捕获Promise { <rejected> 'reason' }。
async function func() {
	return await Promise.reject('reason');
}

console.log(func());

正确写法2.1: 在可能返回promise rejection的函数内使用try/catch结构: 

async function func() {
    try {
        return await Promise.reject('reason');
    } catch(e) {
        console.error(e);
    }
}

func();

运行结果2.1:

正确写法2.2:在调用可能返回promise rejection的函数的末尾链接.catch() 块:

async function func() {
    return await Promise.reject('reason');
}

func()
.catch((e) =>
    console.error(e)
);

运行结果2.2:

正确写法2.3:以await方式调用可能返回promise rejection的函数:

async function func() {
    return await Promise.reject('reason');
}

(async function() {
	try {
	    await func();
	} catch(e) {
	    console.error(e);
	}
})();

运行结果2.3: 

错误写法3.1:用try/catch处理promise rejection;

错误写法3.2:用throw抛出promise rejection: 

function func() {
    throw Promise.reject('reason');
}

try {
	func();
} catch(e) {
	console.error(e);
}

导致后果3:未能处理promise rejection:

出错原因3:try...catch捕获了promise rejection不代表处理了promise rejection。

错误改法3:

async function func() {
    await Promise.reject('reason');
}

try {
	func();
} catch(e) {
	console.error(e);
}

运行结果3:未能处理promise rejection:

改错原因3:func异步非阻塞执行立即返回Promise { <pending> },随后异步返回Promise { <rejected> 'reason' },却未设置处理Promise { <rejected> 'reason' }的语句。

正确写法3.1:先使用async/await将异步promise rejection转换成同步代码的风格,再使用同步 try/catch 结构。

async function func() {
    await Promise.reject('reason');
}

(async () => {
	try {
		await func();
	}
	catch(e) {
		console.error(e);
	}
})();

运行结果3.1:

优化写法3.2:

async function func() {
	try {
	    await Promise.reject('reason');
	} catch(e) {
		console.error(e);
	}
}

func();

 运行结果3.2:

Note: .then()/.catch() blocks in promises are basically the async equivalent of a try...catch block in sync code. Bear in mind that synchronous try...catch won't work in async code.

 错误写法4:使用.catch捕获非async函数中throw抛出的promise rejection:

function func() {
    throw Promise.reject('reason');
}


func()
.catch(console.error);

 导致后果4:语法错误:

正确写法4:

async function func() {
    await Promise.reject('reason');
}

func()
.catch(console.error);

运行结果4:

 错误写法5:在保存await语句返回值的变量的末尾链接.then()或.catch() 块:

async function func() {
    let p = await new Promise(function(resolve,) { 
        setTimeout(() => resolve('value'), 1000);
    });

	p
    .then(console.log)
    .catch(console.error);
}

func();

导致后果5:TypeError:

错误原因5:await语句返回的是Promise resolved后携带的值,而不是Promise本身。 

正确写法5:

async function func() {
    let p = await new Promise(function(resolve,) { 
        setTimeout(() => resolve('value'), 1000);
    });

    console.log(p);
}

func()
.catch(console.error);

运行结果5:

 编程细则1:

If the Promise is rejected, only the await expression throws the rejected value.

/* test1 */
function func() {
	Promise.reject('reason');
}

func()
.catch(console.error);	// TypeError: Cannot read property 'catch' of undefined


/* test2 */
function func() {
	Promise.reject('reason');	// UnhandledPromiseRejectionWarning: reason
}

try {
	func();
} catch(e) {
	console.error(e);
}


/* test3 */
async function func() {
	Promise.reject('reason');	// UnhandledPromiseRejectionWarning: reason
}

func()
.catch(console.error);


/* test4 */
async function func() {
	Promise.reject('reason');	// UnhandledPromiseRejectionWarning: reason
}

try {
	func();
} catch(e) {
	console.error(e);
}


/* test5 */
async function func() {
	await Promise.reject('reason');
}

func()
.catch(console.error);	// reason


/* test6 */
async function func() {
	await Promise.reject('reason');
}

try {
	func();	// UnhandledPromiseRejectionWarning: reason
} catch(e) {
	console.error(e);
}

编程细则2.1:普通函数中Promise.reject语句不会停止当前函数的执行:

function func() {
	console.log(11111);
	Promise.reject('reason');
	console.log(22222);
}

func()
.catch(console.error);
/*
11111
22222
/mnt/hgfs/shared_folder/test.js:8
.catch(console.error);
^

TypeError: Cannot read property 'catch' of undefined
*/

编程细则2.2:如果Promise被拒绝,则await表达式会抛出被拒绝的值,若该值在当前函数内未被捕获,则停止当前函数的执行:

async function func() {
	console.log(11111);
    await Promise.reject('reason');
	console.log(22222);
}

func()
.catch(console.error);
/*
11111
reason
*/

编程细则2.3:如果Promise被拒绝,则await表达式会抛出被拒绝的值,若该值在当前函数内被捕获,则继续当前函数的执行:

async function func() {
	console.log(11111);
    await Promise.reject('reason')
	.catch(console.error);
	console.log(22222);
}

func();
/*
11111
reason
22222
*/

 编程细则3:不能省略return后的await。

保留return后的await,func稍后返回null;

省略return后的await,func立即返回Promise { <pending> }。

async function func() {
	try {
		return await Promise.reject('reason');
	} catch (e) {
		return null;
	}
}

(async function() {
	console.log(await func());
})();

编程细则4:若func的参数依赖于同步阻塞函数的执行结果,则func同步阻塞执行。

async function func1() {
	return await Promise.resolve('222');
}

async function func2() {
	return await Promise.resolve('22');
}

(async function() {
	console.log('11111');
	console.log(await func1() + await func2());
	console.log('33333');
})();
/*
11111
22222
33333
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值