一、啥是回调地狱 先看一段代码:
// 第一版
setTimeout(()=>{
console.log(111);
setTimeout(()=>{
console.log(222);
setTimeout(()=> {
console.log(333);
},1000)
},2000);
},3000)
像这样的代码就是回调地狱,这段代码意思很明确,就不过多说明了 这段代码可以适当封装一下:
// 第二版
const createTimer = (callback, delay) => {
let timer = null;
return () => {
clearTimer(timer);
timer = setTimeout(callback, delay);
};
};
const timer1 = createTimer(()=>{
console.log(111);
const timer2 = createTimer(()=>{
console.log(222);
const timer3 = createTimer(()=>{
console.log(333);
},1000);
timer3();
},2000);
timer2();
},3000)
timer1();
看到了没,回调地狱式的写法,不管怎么封装,它始终都是嵌套在一起的,可读性极差,这还是比较简单的情况。层级越复杂会嵌套得越深,可读性越差。
二、如何解决回调地狱 如何解决,使用Promise:
// 第三版
const createTimer = (callback, delay) => {
let timer = null;
return () => {
clearTimer(timer);
timer = setTimeout(callback, delay);
};
};
// 封装promise
const getPromise = (data, time) => {
return new Promise((resolve, reject)=>{
const timer1 = createTimer(() => {
resolve(data);
}, time);
timer1();
});
}
// 调用promise
const promise1 = getPromise(111,3000);
promise1.then(res=>{
console.log(res);
const promise2 = getPromise(222,2000);
return promise2;
}).then(res=>{
console.log(res);
const promise3 = getPomise(333,1000);
return promise3;
}).then(res=>{
console.log(res);
})
promise 的用法是将传递的数据通过resolve或reject保存到promise对象中,通过then方法获取数据。 用了promise后,可以直观的发现代码可读性有一定的提高,它解决了异步函数的执行顺序问题。 但链式调用可读性还是很差,并且也不容易调试。 再介绍一下async/await
三、async/await
// 第四版
const createTimer = (callback, delay) => {
let timer = null;
return () => {
clearTimer(timer);
timer = setTimeout(callback, delay);
};
};
// 封装promise
const getPromise = (data, time) => {
return new Promise((resolve, reject)=>{
const timer1 = createTimer(() => {
resolve(data);
}, time);
timer1();
});
}
// 使用 async/await
const AsyncFunction = async () => {
const res1 = await getPromise(111,3000);
console.log(res1);
const res2 = await getPromise(222,2000);
console.log(res2);
const res3 = await getPromise(333,1000);
console.log(res3);
}
AsyncFunction();
这里我们可以发现 async/await 摆脱了链式调用, 更像是同步代码,看起来更加的优雅简洁。 大家可以把这三种写法详细对比一下,体会一下差异在哪。