一:为什么需要promise
传统通过ajax请求数据,需要在回调函数中层层嵌套回调,这种结构叫做回调地狱,不利于阅读和后期维护
Promise出现正好解决了回调地狱 。
二:Promise的基本使用
Promise是一个构造函数,通过new关键字实例化对象
语法:
new Priomise((resolve, reject)=> { })
- Promise接收一个函数作为参数
- 在参数函数中接收两个参数
参数一: resolve–>成功函数
参数二 :reject–>失败函数
三:Promise实例
Promise实例有两个属性 :
- state:状态
result:结果
打印Promise实例:
<body><script>const p = new Promise((resolve, reject) => {})console.log(p)</script></body>
1:Promise的状态
第一种状态:pending(准备,带解决,进行中)
第二种状态:fulfilled(已完成,成功)
第三种状态:rejected(已拒绝,失败2:Promise状态的改变
通过调用resolve()和reject()改变当前Promise对象的状态 :
resolve():调用函数,使当前promise对象的状态改变成fulfilled
reject():调用函数,使当前promise对象的状态改变成rejected
Promise状态的改变是一次性的。调用resolve()函数并输出结果:
<body><script>const p = new Promise((resolve, reject) => {//resolve():调用函数,使当前promise对象的状态改变成fulfilledresolve()})console.log(p)</script></body>

调用reject()函数并输出结果:<body><script>const p = new Promise((resolve, reject) => {//reject():调用函数,使当前promise对象的状态改变成rejectedreject()})console.log(p)</script></body>
同时调用resolve()和reject()函数并输出结果:<body><script>const p = new Promise((resolve, reject) => {//同时调用reject()和resolve(),对promise状态的改变是一次性的;//并不会reject()修改状态为rejected,再调用resolve()后把状态从rejected修改为fulfilled//reject()先行,所以状态一次性改为rejectedreject()resolve()})console.log(p)</script></body>
3:Promise的结果
1、通过调用resolve(),传递参数,改变当前Promise对象的结果 :
body><script>const p = new Promise((resolve, reject) => {resolve('成功的结果')})console.log(p)</script></body>

2、通过调用reject(),传递参数,改变当前Promise对象的结果 :<body><script>const p = new Promise((resolve, reject) => {reject('失败的结果')})console.log(p)</script></body>
三:Promise的方法
1:then()方法
then()方法是存在于Promise原型上的一个方法
then()方法同时也是一个函数,有两个参数:
1、是一个函数
2、还是一个函数
返回值:是一个新的Promise对象,而且此时状态还是pending<body><script>const p = new Promise((resolve, reject) => {reject('失败的结果')})//p.then()返回值还是一个Promise对象const t = p.then(() => {console.log('成功时调用')}, () => {console.log('失败时调用')})console.log(t)</script></body>

当promise的状态是fulfilled时,执行第一个参数函数体的内容;当promise的状态是rejected时,执行第二个参数函数体的内容。
对于为什么在then()方法的参数函数中,可以通过形参使用promise对象的结果呢?以下这张图是自己一些简单理解:
Promise的状态不改变,不会执行then里的方法。
在then()方法中,通过return将返回的promise实例改为fulfilled状态。
<body><script>const p = new Promise ((resolve, reject) => {//1、使用resolve()回调,修改p实例化对象的状态为fulfilled,//从而会执行p.then()中第一个参数函数体内容resolve()})const t = p.then((value) => {console.log('成功')//2、使用return可以将t实例化对象的状态改变成fulfilled,//从而会执行t.then()中第一个参数函数体内容return 123}, (reason) => {console.log('失败')})t.then((value) => {//3、执行console.log('成功2', value)console.log('成功2', value)}, (reason) => {console.log('失败2')})</script></body>

如果在then()方法的第一个参数函数中,出现代码错误,会将返回的Promise实例的状态改变成rejected:
<body><script>const p = new Promise ((resolve, reject) => {//1、使用resolve()回调,修改p实例化对象的状态为fulfilled,//从而会执行p.then()中第一个参数函数体内容resolve()})const t = p.then((value) => {console.log('成功')//2、这里代码出错,会将t实例化对象的状态改变成rejectedconsole.log(a)}, (reason) => {console.log('失败')})t.then((value) => {console.log('成功2', value)//3、执行console.log('失败2', reason)}, (reason) => {console.log('失败2', reason)})</script></body>
2:catch()方法
catch中参数函数在什么时候被执行?
1、当Promise的状态改为rejected时,被执行:
<body><script>const p = new Promise ((resolve, reject) => {reject()})p.catch((reason) => {console.log('失败', reason)})</script></body>

2、当Promise执行体中出现代码错误时,被执行
<body><script>const p = new Promise ((resolve, reject) => {console.log(a)})p.catch((reason) => {console.log('失败', reason)})</script></body>

四:使用Promise解决回调地狱
<body><script>//传统发送ajax请求,层层嵌套-->回调地狱$.ajax({type: 'GET',url: './data1.json',success: function (res) {const {id} = res$.ajax({type: 'GET',url: './data2.json',data: {id},success: function (res) {const {username} = res$.ajax({type: 'GET',url: './data3.json',data: { username },success: function (res) {console.log(res)//最终成功打印输出:"SWK@123456.com"}})}})}})//使用Promise解决回调地狱new Promise((resolve, reject) => {$.ajax({type: 'GET',url: 'data1.json',success: function (res) {//调用resolve(),保存从ajax返回数据res,并作为promise的结果,同时修改状态为fulfilledresolve(res)},error: function (res) {//修改promise的状态为rejected,修改promise的结果resreject(res)}})}).then((data) => {//对象解构const { id } = datareturn new Promise((resolve, reject) => {$.ajax({type: 'GET',url: 'data2.json',data: { id },success: function (res) {//调用resolve(),保存从ajax返回数据res,并作为promise的结果,同时修改状态为fulfilledresolve(res)},error: function (res) {//修改promise的状态为rejected,修改promise的结果resreject(res)}})})}).then((data) => {//对象解构const { username } = datareturn new Promise((resolve, reject) => {$.ajax({type: 'GET',url: 'data3.json',data: { username },success: function (res) {//调用resolve(),保存从ajax返回数据res,并作为promise的结果,同时修改状态为fulfilledconsole.log(res)//最终成功打印输出:"SWK@123456.com"}})})})</script></body>
优化代码:
<body><script>function getData(url, data = {}) {return new Promise((resolve, reject) => {$.ajax({type: 'GET',url: url,data: data,success: function (res) {//调用resolve(),保存从ajax返回数据res,并作为promise的结果,同时修改状态为fulfilledresolve(res)},error: function (res) {//修改promise的状态为rejected,修改promise的结果resreject(res)}})})}getData('data1.json').then((data) => {//对象解构const { id } = datareturn getData('data2.json', { id })}).then((data) => {//对象解构const { username } = datareturn getData('data3.json', { username })}).then((data) => {console.log(data)})</script></body>
