异步方法实现同步
需求:现在有fnA、fnB、fnC三个异步方法(可类比异步请求),fnB需要fnA结束才能调用,fnC需要fnB结束才能调用
- async/await 简单粗暴,墙裂推荐!
async function async_await() {
const resA = await fnA()
const resB = await fnB()
const resC = await fnC()
}
- promise
console.log(`方法A开始...`)
new Promise(fnA)
.then(resA => {
console.log(`方法A结果:`, resA, `方法B开始...`)
return new Promise(fnB)
}).then(resB => {
console.log(`方法B结果:`, resB, `方法C开始...`)
return new Promise(fnC)
}).then(resC => {
console.log(`方法C结果:`, resC)
})
const fnA = (resolve, reject) => {
setTimeout(() => {
console.log(`方法A完成`)
resolve(`方法A_data`)
}, 3000)
}
const fnB = (resolve, reject) => {
setTimeout(() => {
console.log(`方法B完成`)
resolve(`方法B_data`)
}, 3000)
}
const fnC = (resolve, reject) => {
setTimeout(() => {
console.log(`方法C完成`)
resolve(`方法C_data`)
}, 3000)
}
reject,then的第二个回调函数,catch
总结:
- then有两个回调,promise.then(onCompleted, onRejected),promise里resolve则执行onCompleted,reject则执行onRejected
- reject 是 Promise 的方法,而 catch 是 Promise 实例的方法
- reject 是用来抛出异常,then的第二个回调函数和catch 是用来处理异常
- promise内reject后的东西,一定会进入then中的第二个回调,且不会中止链式调用之后的代码执行;如果then中没有写第二个回调,则进入catch,且会中止链式调用之后的代码执行
- 网络异常(比如断网),会直接进入catch而不会进入then的第二个回调
没有then的第二个回调函数
现在在第二个promise(fnB)中使用reject抛出,我们可以在整个链的最后添加catch。可以看到resolve的promose正常执行,直到链中的某个promise执行了reject,则会跳过后边所有链式调用,直接执行catch
console.log(`方法A开始...`)
new Promise((resolve, reject) => {
setTimeout(() => {
//fnA()
console.log(`方法A成功`)
resolve('方法A_data')
}, 3000)
}).then(resA => {
console.log(`方法B开始...`)
return new Promise((resolve, reject) => {
setTimeout(() => {
//fnB()
console.log(`方法B失败`)
reject(`方法B_reason`)
}, 3000)
})
}).then(resB => console.log(`方法B结果:`, resB))
.catch(err => console.log(`err`, err))
//打印结果
//方法A开始...
//方法A成功
//方法B开始...
//方法B失败
//err 方法B_reason
有then的第二个回调函数
我们现在定义一个then的第二个参数
const onRejected = resson => console.log('resson: ', resson);
这次让第一个promise(fnA)执行reject,在对应的then中添加我们定义的第二个参数onRejected。可以看到onRejected执行了,catch没有执行,而且注意,之后的链式调用并没有中止
console.log(`方法A开始...`)
new Promise((resolve, reject) => {
setTimeout(() => {
//fnA()
console.log(`方法A失败`)
reject('方法A失败_reason')
}, 3000)
}).then(
resA => {
console.log(`方法B开始...`)
return new Promise((resolve, reject) => {
setTimeout(() => {
//fnB()
console.log(`方法B成功`)
resolve(`方法B_data`)
}, 3000)
})
},
onRejected
).then(resB => console.log(`方法B结果:`, resB))
.catch(err => console.log(`err`, err))
// 打印结果
// 方法A开始...
// 方法A失败
// resson: 方法A失败_reason
// 方法B结果: undefined