Promise#
定义#
Promise :一个表示(管理)异步操作最终的完成(或失败)以及其结果值的 对象
好处:
- 逻辑更清晰
- 了解axios函数内部运作机制
- 能解决回调函数地狱问题
语法:
// 1.创建Promise对象
const p = new Promise((resolve, reject) => {
// 2.执行异步任务,并传递结果
// 成功调用:resolve(值) 触发 then()执行
// 失败调用:reject(值) 触发 catch()执行
});
// 3.接收结果
p.then(result => {
// 成功
}).catch(error => {
// 失败
})
初体验:使用Promise管理异步任务
// 1.创建Promise对象
const p = new Promise((resolve, reject) => {
// 2.执行异步代码
setTimeout(() => {
// resolve('模拟AJAX请求-成功结束')
reject(new Error('模拟AJAX请求-失败结果'))
}, 2000);
});
// 3.获取结果
p.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
Promise对象的三种状态#
作用:了解Promise对象如何关联的处理函数,以及代码执行顺序
概念:一个Promise对象,必然处于以下三种状态之一
-
pending
待定:初始状态,既没有兑现,也没有被拒绝 -
fullfilled
已兑现:操作成功完成执行了
resolve()
时,立即处于该状态,表示Promise已经被解决,任务执行成功 -
rejected
已拒绝:操作失败执行了
reject()
时,立即处于该状态,表示 Promise已经被拒绝,任务执行失败。
注意:Promise对象一旦被 兑现/拒绝 就是 已敲定 了,状态无法再被改变
// 1.创建Promise对象(pending-待定状态)
const p = new Promise((resolve, reject) => {
console.log('Promise对象创建时,里面的代码立即执行');
// 2.执行异步代码
setTimeout(() => {
// resolve()=>'fullfilled状态-已兑现'=>then()
resolve('模拟AJAX请求-成功结束');
// reject()=>'rejected状态-已拒绝'=>catch()
// reject(new Error('模拟AJAX请求-失败结果'))
}, 2000);
});
console.log(p); // {[[PromiseState]]:pending/fullfilled/rejected}
// 3.获取结果
p.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
案例-Promise+XHR获取省份列表#
需求:使用Promise管理XHR获取省份列表,回显到页面
步骤:
- 创建Promise对象
- 执行XHR异步代码,获取省份列表
- 关联成功或失败函数,做后续处理
// 1.创建Promise对象
const p = new Promise((resolve, reject) => {
// 2.XHR请求省份列表
const xhr = new XMLHttpRequest()
xhr.open('get', 'http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend', function() {
console.log(xhr.response);
// xhr如何判断相应成功或失败
// 2xx开头的响应状态码为成功
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()
})
// 3.关联成功或失败函数,做后续处理
p.then(res => {
console.log(res);
document.querySelector('.provincebox').innerHTML = res.list.join('---')
}).catch(err => {
// 错误对象要用console.dir详细打印
console.dir(err);
document.querySelector('.provincebox').innerHTML = err.message
})