在了解回调地狱之前,我们先来了解一下回调函数
回调函数:就是把一个函数当作一个函数的参数
回调地狱:
当异步操作想要有顺序时,只能在一个异步成功以后的回调函数里面嵌套另一个异步的操作,如果嵌套的层数过多就形成了回调地狱
回调地狱的弊端:后期代码维护比较困难
这时我们就可以用promise来解决
promise封装了异步操作。创建一个promise对象,写一个函数作为参数,这个函数参数有两个参数,分别是resolve和reject。函数内部写异步操作,成功调resolve,失败调reject。这时promise对象就可以知道异步操作的状态。p.then(成功执行)p.catch(失败执行)
promise本质就是一个状态机,记录异步内部操作的状态
let p=new Promise(function(resolve,reject){
setTimeout(()=>{
//resolve()//成功调用
// reject() 失败调用
},5000)
})
p.then(console.log("成功"))
p.catch(console.log("失败"))
当你要执行下一个异步操做,需要在then里面写。这样说的话,它还是有一层嵌套
async await 回调地狱的最终解决方法 (es7)
原理:实际上就是生成器函数的语法糖
可以将异步嵌套的语法,改成像是同步一样。不需要嵌套,就可以有先后顺序
使用:
1.定义一个函数,函数前面加async
2.函数里面可以写异步操作,异步操作必须被promise封装
3.promise对象前面写一个 await,就会等promise'里的异步操作成功以后再往下执行
红绿灯案例:
function wait(interval) {
return new Promise((r, j) => {
//同步
setTimeout(() => {
r(interval);
}, interval);
});
}
wait(1000).then(function (r) {
console.log(r);
// 异步
});
async function fn() {
console.log("红");
await wait(3000);
console.log("黄");
await wait(3000);
console.log("绿");
await wait(3000);
fn();
}
fn();
他这个还有一个缺点,只会执行成功的代码。需要配合try catch 使用
let ajaxP = {
get(url) {
return new Promise((r, j) => {
let xhr = new XMLHttpRequest();
xhr.open("get", url);
xhr.send();
xhr.onload = function () {
if (xhr.status == 200) {
let obj = JSON.parse(xhr.responseText);
r(obj);
}
};
});
},
};
// ajaxP.get('url').then().catch().finally()
async function box() {
//await 会等 后面的promise对象成功以后再往下执行
//await 必须使用到async 修饰的函数内部
// await promise对象
try {
let r = await ajaxP.get('url');
console.log(r);
} catch (error) {
}