下面的文字注意看每块代码最后的打印值,以及代码中的注释
普通 reject
// 代码1
function testRej() {
let _res, _rej
let pro = new Promise((res, rej) => {
_res = res
_rej = rej
})
async function abc() {
try {
setTimeout(() => {
_rej(123)
}, 3000)
return pro
} catch(err){
console.log('try catch err', err)
}
}
abc().then(res => {
console.log('then', res)
}).catch(err => {
console.log('catch', err)
})
}
/**
* 打印值:
* catch 123
* 上面的代码直接执行到了 return pro,
* 然后在 3 秒后 _rej 后进入了 abc() 的 catch
*/
testRej()
未被 catch 的 reject
promise reject 后,没有被catch的话,目前不会结束代码运行。会继续执行后续代码,不过会在最后报个警告: UnhandledPromiseRejectionWarning。并提示在后续的 node 版本中会导致进程非正常结束,就是崩掉。
这里下面的 2 块代码中,下面那块代码的区别是新增了 _rej(456) 这行。
// 代码2
function testReject1() {
let _res, _rej
let pro = new Promise((res, rej) => {
_res = res
_rej = rej
})
async function abc() {
try {
Promise.reject(666)
console.log(111222444)
// 本例这里这个 pro 一直没有被 resolve 或 reject,所以没有后续关于他的打印值
return pro
} catch(err){
console.log('catch err', err)
}
}
abc().then(res => {
console.log('then', res)
}).catch(err => {
console.log('catch', err)
})
}
/**
* 打印值:
* 111222444
* (node:62686) UnhandledPromiseRejectionWarning: 666
*/
testReject1()
// 代码3
function testReject2() {
let _res, _rej
let pro = new Promise((res, rej) => {
_res = res
_rej = rej
})
async function abc() {
try {
_rej(456)
Promise.reject(666)
console.log(111222444)
return pro
} catch(err){
console.log('catch err', err)
}
}
abc().then(res => {
console.log('then', res)
}).catch(err => {
console.log('catch', err)
})
}
/**
* 打印值:(这个顺序涉及宏任务微任务而已)
* 111222444
* catch 456
* (node:62686) UnhandledPromiseRejectionWarning: 666
*/
testReject2()
测试立即 throw
throw 后面的同步代码不再执行,而且 throw 具有穿透性。
// 代码4
function testThrow1() {
let _res, _rej
let pro = new Promise((res, rej) => {
_res = res
_rej = rej
})
async function abc() {
try {
throw '立即throw'
console.log('after 立即throw')
return pro
} catch(err){
console.log('catch err', err)
return 'trycatch return'
}
}
abc().then(res => {
console.log('then', res)
}).catch(err => {
console.log('catch', err)
})
}
/**
* throw 后面的同步代码不再执行,而且 throw 具有穿透性
*
* 打印值:
* catch err 立即throw
* then trycatch return
*/
testThrow1()
测试异步 throw
// 代码5
function testThrow2() {
let _res, _rej
let pro = new Promise((res, rej) => {
_res = res
_rej = rej
})
async function abc() {
try {
setTimeout(() => {
// 不管这个 _rej(123) 是否打开,都报的一样的打印值,
// 应该是 throw 后,js 进程就退出了,后面本来该报的 catch 123 也报不了了
// _rej(123)
console.log('before 延迟throw')
// 定时器这里,在后续时间 throw 的错误,
// 不会进入 try catch 中的 catch,会成为全局 throw 的错误。
// try catch 收到的是同步(含aa)的错误
throw '延迟throw'
}, 1000)
return pro
} catch(err){
console.log('catch err', err)
}
}
abc().then(res => {
console.log('then', res)
}).catch(err => {
console.log('catch', err)
})
}
/**
* 定时器这里,在后续时间 throw 的错误,
* 不会进入 try catch 中的 catch,会成为全局 throw 的错误。
* try catch 收到的是同步(含aa)的错误
*
* 打印值:
* before 延迟throw
* 报全局的 延迟throw 错误
*/
testThrow2()