一:为什么需要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对象的状态改变成fulfilled
resolve()
})
console.log(p)
</script>
</body>
调用reject()函数并输出结果:<body>
<script>
const p = new Promise((resolve, reject) => {
//reject():调用函数,使当前promise对象的状态改变成rejected
reject()
})
console.log(p)
</script>
</body>
同时调用resolve()和reject()函数并输出结果:<body>
<script>
const p = new Promise((resolve, reject) => {
//同时调用reject()和resolve(),对promise状态的改变是一次性的;
//并不会reject()修改状态为rejected,再调用resolve()后把状态从rejected修改为fulfilled
//reject()先行,所以状态一次性改为rejected
reject()
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实例化对象的状态改变成rejected
console.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的结果,同时修改状态为fulfilled
resolve(res)
},
error: function (res) {
//修改promise的状态为rejected,修改promise的结果res
reject(res)
}
})
}).then((data) => {
//对象解构
const { id } = data
return new Promise((resolve, reject) => {
$.ajax({
type: 'GET',
url: 'data2.json',
data: { id },
success: function (res) {
//调用resolve(),保存从ajax返回数据res,并作为promise的结果,同时修改状态为fulfilled
resolve(res)
},
error: function (res) {
//修改promise的状态为rejected,修改promise的结果res
reject(res)
}
})
})
}).then((data) => {
//对象解构
const { username } = data
return new Promise((resolve, reject) => {
$.ajax({
type: 'GET',
url: 'data3.json',
data: { username },
success: function (res) {
//调用resolve(),保存从ajax返回数据res,并作为promise的结果,同时修改状态为fulfilled
console.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的结果,同时修改状态为fulfilled
resolve(res)
},
error: function (res) {
//修改promise的状态为rejected,修改promise的结果res
reject(res)
}
})
})
}
getData('data1.json')
.then((data) => {
//对象解构
const { id } = data
return getData('data2.json', { id })
})
.then((data) => {
//对象解构
const { username } = data
return getData('data3.json', { username })
})
.then((data) => {
console.log(data)
})
</script>
</body>