promise解决回调地狱相关

回调地狱

回调地狱指多个回调函数嵌套
还记得回调函数吗? 就是调用自身啊
下面用代码解释写法繁琐但写法合法的回调地狱 :

首先创建三个json文件 : a.json   b.json   c.json
内容分别为 : {"aa" : "hello"}	{"bb" : "world"}	{"cc" : "html"}
$.ajax({
    url:"a.json",
    dataType:"json",
    success(data){	//请求到a的数据之后再去请求b的数据
        $.ajax({
            url:"b.json",
            dataType:"json",
            success(data){	//请求到b的数据之后,再去请求c的数据
                $.ajax({
                    url:"c.json",
                    dataType:"json",
                    success(data){
                       console.log(data); //{cc : "html"}
                    }
                })
            }
        })
    }
})

Promise对象

Promise对象主要把回调函数嵌套的写法变成链式写法

Promise对象里放的是异步操作的代码,异步操作的代码的状态会从等待状态变为成功状态或者是失败状态,当他的状态发生改变的时候就会触发.then方法,.then方法里有两个函数,第一个是成功的函数,第二个是失败的函数

jq的 $.ajax返回的本身就是一个promise对象,可以直接调用then方法,假设$.ajax返回的不是promise的话我们需要自己new Promise方法 ,才能调用then方法

(1) 一个ajax请求的时候

// 原生的写法
function js_pro(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open("get", url, true);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    var data = xhr.responseText;
                    resolve(data);
                } else {
                    reject("404");
                }
            }
        }
    })
}
js_pro("a.json").then(res=>{
    delDate(res);	//成功的回调函数中可以使用封装函数
},res=>{

})
function delDate(data){
    console.log(data);	// {aa : "hello"}
}

//jq写法
function jq_pro(url,data){
    return $.ajax({
        url,
        data,
        dataType:"json",
    })
}
jq_pro("a.json").then(res=>{
    delDate(res);
},res=>{

})

(2) 多个ajax请求的时候 ( 回调地狱 ) , 返回新的promise实例 , 可以链式调用

// 原生的写法
function js_pro(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open("get", url, true);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    var data = xhr.responseText;
                    resolve(data);
                } else {
                    reject("404");
                }
            }
        }
    })
}
js_pro("a.json").then(res=>{
    return js_pro("b.json");
}).then(res=>{
    return js_pro("c.json");
}).then(res=>{
    console.log(data);	//{cc : "html"}
})

//jq写法
function jq_pro(url,data){
    return $.ajax({
        url,
        data,
        dataType:"json",
    })
}
jq_pro("a.json").then(res=>{
    return jq_pro("b.json");
}).then(res=>{
    return jq_pro("c.json");
}).then(res=>{
    console.log(data);	//{cc : "html"}
})

(3) 多个ajax请求的时候 ( 互相没有关系 ) Promise.all

当页面中有多个ajax请求,而且他们之间没有关系,就可以用promise.all发送多个promise异步操作 , 只有这多个异步请求全都成功了才会执行then方法

function jq_pro(url,data){
    return $.ajax({
        url,
        data,
        dataType:"json"
    })
}
Promise.all([
    jq_pro("a.json"),
    jq_pro("b.json"),
    jq_pro("c.json")
]).then(res=>{
    console.log(res);	//[{aa:"hello"},{bb:"world"},{cc:"html"}]
})

Promise . race 请求多个promise , 只要有一个响应成功了就会触发.then

Promise.race([
	jq_pro("a.json"),
	jq_pro("b.json"),
	jq_pro("c.json")
]).then(res=>{
    console.log(res);	//{aa:"hello"}或{bb:"world"}或{cc:"html"}看哪个json文件先响应
})

promise的错误处理有两种写法:

  1. then 方法里放两个函数 , 第一个是成功的回调 , 第二个是失败的回调
  2. then 方法里放成功的回调,继续.catch放失败的回调 jq 的 ajax 比较特殊,因为他是自己已经封装好的promise对象,catch的写法变成了fail

catch会捕捉到错误 , 之后的代码不执行

(1) 一个ajax的错误处理

// jq写法
function jq_pro(url,data){
   return $.ajax({
       url,
       data,
       dataType:'json'
   })
}
jq_pro("a.json").then(res=>{
	console.log(res);
}).fail(res=>{
    console.log(res);
})
// js写法
function js_pro(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open("get", url, true);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    var data = xhr.responseText;
                    resolve(data);
                } else {
                    reject("404");
                }
            }
        }
    })
}
js_pro("a.json").then(res=>{
	console.log(res);
}).catch(res=>{
    console.log(res);
})

(2) 多个ajax回调地狱的错误处理

js_pro("a.json").then(res=>{
    return js_pro("b.json");
}).then(res=>{
    return js_pro("c.json");
}).then(res=>{
    console.log(res);
}).catch(res=>{
    console.log(res);
})

(3) 多个ajax没有关系

Promise.all([
   js_pro("a.json"),
   js_pro("b.json"),
   js_pro("c.json")
]).then(res=>{
   console.log(res);
}).catch(res=>{
   console.log(res);
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值