个人很喜欢把async await promise try catch throw联合使用,以达到精准控制程序流的目的,最终目的只有一个:使用主动throw/reject,大量减少return 和 if,代码量少很多,特别是遇到函数调用很深的情况,如果要一层一层往外return 再 if判断结果决定是否继续执行时,是非常难受的, 代码也容易写得非常复杂。
throw的出发点只有一个:
是否要让程序继续执行下去 ?不执行下去就直接throw,让trycatch抓住,终止程序流。
注意:trycatch 的使用要保证当前所有调用都有序进行,确保连环调用
promise中的reject 等同于 throw
!(async function () {
try {
await new Promise((resolve, reject) => {
reject('reject 一个错误')
})
} catch (error) {
console.log(error) //reject 一个错误
}
})()
//等价于
!(async function () {
try {
await new Promise((resolve, reject) => {
throw 'throw 一个错误'
})
} catch (error) {
console.log(error) //throw 一个错误
}
})()
throw语句精准控制程序流
//示例1:终止 forEach
function forEachFn() {
const arr = [1, 2, 4, 5];
arr.forEach(item => {
if (item === 1) throw '强行终止forEach'
})
console.log('forEach next') // 不会执行到这里
}
!(async function () {
try {
forEachFn()
console.log('forEach next2') // 不会执行到这里
} catch (error) {
console.log(error) //强行终止forEach
}
})()
//示例2:终止 switch case
function switchCase(key) {
switch (key) {
case 1:
throw '强行终止 switch case'
}
console.log('switchCase next') // 不会执行到这里
}
!(async function () {
try {
switchCase(1)
console.log('switchCase next2') // 不会执行到这里
} catch (error) {
console.log(error) //强行终止 switch case
}
})()
//示例3:终止递归
function runRecursion(index = 1) {
if (index === 3) throw '终止递归'
return runRecursion(index += 1)
}
!(async function () {
try {
runRecursion()
console.log('runRecursion') // 不会执行到这里
} catch (error) {
console.log(error) //终止递归
}
})()
有些同学可能会担心trycatch 的性能问题
事实上,有性能问题的在于catch语句,但是可以避免。这里引用高性能javascript中给出的解决方案,书很老,但很实在。本人用当前最新的chrome浏览器和微信开发者工具验证过了,此方案可行,没有性能问题
是否要用throw抛异常来终止程序流,争论已久,私认为,使用throw代码可靠性和维护性更高,因为我们最终的目的是为了让程序不再执行下去,如果使用return + if的方式,比较容易造成误操作,万一下面的判断不够准确,程序流就崩了。但如果直接抛异常,开发的时候就能很明确,程序执行到哪个节点被我们主动停下来了,而且程序流也一定被终止了,这样非常可靠。
以上有任何不对的地方,欢迎指正,谢谢你