当后续的Promise需要用到之前的Promise的处理结果时,需要Promise的串联
Promise对象中,无论是then方法还是catch方法,**它们都具有返回值,返回的是一个全新的Promise对象**,它的状态满足下面的规则:
1. 如果当前的Promise**是未决的,得到的新的Promise是挂起状态
2. 如果当前的Pro**mise是已决的,会运行响应的后续处理函数,并将后续处理函数的结果(返回值)作为resolved状态数据,应用到新的Promise中;如果后续处理函数发生错误,则把返回值作为rejected状态数据,应用到新的Promise中。
后续的Promise一定会等到**前面的Promise有了后续处理结果后,才会变成已决状态
3.如果前面的Promise的后续处理,返回的是一个Promise,则返回的新的Promise状态和后续处理返回的Promise状态保持一致。
示例1
const pro = new Promise ((resolve,reject) =>{})const pro2 = pro.then(value =>{return value;})pro2.then(value =>{console.log(1)})
当其 unsettled阶段为pending状态 说明此时还没结果,所以后面的settled阶段是不会执行的,后面在得到新的promise也会是pending状态
示例2
如果当前的Pro**mise是已决的,会运行响应的后续处理函数,并将后续处理函数的结果(返回值)作为resolved状态数据,应用到新的Promise中;如果后续处理函数发生错误,则把返回值作为rejected状态数据,应用到新的Promise中。**
const pro = new Promise((resolve,reject) =>{resolve(1)})const pro2 = pro.then(value =>{throw 2})pro2.then(value => console.log(value),err => console.log(err))

pro.then进入啦resolved状态,但是内部代码报错那吗pro2就会接受错误信息进入rejected状态
const pro = new Promise((resolve,reject) =>{throw 2})console.log(pro)const pro2 = pro.then(value =>{// throw 2},err => err * 2 )pro2.then(value => console.log(value),err => console.log(err * 2 ))

如上面代码,pro在unsettled阶发送需错误信息 但是 pro在rejected状态并没抛出错误,而是进行运算,那这样就是是后续代码没有出现错误,pro2进入resolved 状态,这说明新的promise 进入那种状态时看它的上一个promise后续处理函数是否出错,没出错那就接受resolved状态数据,反之就接受rejected状态数据
示例3
如果前面的Promise的后续处理,返回的**是一个Promise,则返回的新的Promise状态和后续处理返回的Promise状态保持一致
注意then方法与catch放发返回的时promise对象 ,此处说的是返回一个promise**
const pro = new Promise((resolve,reject)=>{resolve(1)})const pro2 = new Promise((resolve,reject)=>{resolve(2)})const pro3 = pro.then(value =>{//返回一个promisereturn pro2;})pro3.then(value =>{console.log(value) // 结果为 2})
示例4
const pro = new Promise((resolve,reject)=>{resolve(1)})pro.then(value =>{return 1}).then(value =>{value = 2//函数默认返回值为unfinished}).then(value =>{console.log(value) //结果为unfinished}

此代码中pro的第二个处理函数并没有设置返回值,函数将其默认值unfinished返回,而pro的第三个处理函数却接受的unfinished的值
案例1
回调地狱
<script src="./ajax.js"></script><!-- 获取李华所在班级的老师的信息 --><script>ajax({url: "./data/students.json?name=李华",success: function (data) {console.log(data)for (let i = 0; i < data.length; i++) {if (data[i].name === '李华') {const cid = data[i].classId;ajax({url: "./data/classes.json?id=" + cid,success(data) {console.log(data)for (let j = 0; j < data.length; j++) {if (data[j].id === cid) {const tid = data[j].teacherId;ajax({url: "./data/teachers.json?id=" + tid,success(data) {for (let i = 0; i < data.length; i++) {if (data[i].id === tid) {console.log(data[i])}}}})}}}})}}}})</script>
promise
// 辅助函数,把传进来的对象拼接成url的字符串function toData(obj) {if (obj === null) {return obj;}let arr = [];for (let i in obj) {let str = i + "=" + obj[i];arr.push(str);}return arr.join("&");}// 封装Ajaxfunction ajax(obj) {return new Promise((resolve, reject) => {//指定提交方式的默认值obj.type = obj.type || "get";//设置是否异步,默认为true(异步)obj.async = obj.async || true;//设置数据的默认值obj.data = obj.data || null;// 根据不同的浏览器创建XHR对象let xhr = null;if (window.XMLHttpRequest) {// 非IE浏览器xhr = new XMLHttpRequest();} else {// IE浏览器xhr = new ActiveXObject("Microsoft.XMLHTTP");}// 区分get和post,发送HTTP请求if (obj.type === "post") {xhr.open(obj.type, obj.url, obj.async);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");let data = toData(obj.data);xhr.send(data);} else {let url = obj.url + "?" + toData(obj.data);xhr.open(obj.type, url, obj.async);xhr.send();}// 接收返回过来的数据xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {resolve(JSON.parse(xhr.responseText))} else {reject(xhr.status)}}}})}// 开始查询const pro = ajax({url: './data/students.json'})pro.then(value => {for (let i = 0; i < value.length; i++) {if (value[i].name === '李华') {return value[i].classId}}}).then(cid => {return ajax({url: "./data/classes.json?id=" + cid,}).then(value => {for (let i = 0; i < value.length; i++) {if (value[i].id === cid) {return value[i].teacherId}}})}).then(tid => {return ajax({url: "./data/teachers.json?id=" + tid,}).then(value =>{for (let i = 0; i < value.length; i++) {if(value[i].id === tid){console.log(value[i])}}})})
从上面两个代码中es6之前的回调地狱的代码及其不易看懂,毕竟嵌套太多观察起来很不容易,es6的promise,并不有减少代码而是消除回调地狱,不会让他无限回调下去而是将回调变得可以控制,把它每一块都分开啦,每一个then方法处理一个步骤处理完后交个下一个promise处理 以此形成一个串联关系
