Promise的理解和使用
-
理解
抽象表达:
-
Promise是一门新的技术(ES6规范)。
-
Promise是JS中进行异步编程的解决方案。(旧方案是单纯调用回调函数)
具体表达:
- 从语法上来说:Promise是一个构造函数
- 从功能上来说:Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值。
-
-
优点
指定回调函数的方式更加灵活
- 旧的:必须在启动异步任务之前指定
- Promise:启动异步任务 => 返回promise对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定)
支持链式调用,可以解决回调地狱问题
-
回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件。
-
回调地狱的缺点:
不便于阅读
不便于异常处理
-
解决方案
promise链式调用
-
使用Promise发送AJAX请求
-
创建promise
const p = new Promise((resolve,reject)=> {})
-
创建xhr对象并发送AJAX请求
// 1.创建对象 const xhr = new XMLHttpRequest(); // 2.初始化 xhr.open('GET','https://api.apiopen.top/getJoke'); // 3.发送 xhr.send(); // 4. 绑定事件处理响应结果 xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ // 判断响应状态码 2xx if(xhr.status >= 200 && xhr.status < 300){ // 控制台输出响应体 resolve(xhr.response); }else{ // 控制台输出响应码 reject(xhr.status); } } }
-
调用 then 方法
p.then(value=>{ console.log(value); }, reason=>{ console.warn(reason); })
-
-
使用Promise封装AJAX请求
-
封装一个函数 sendAJAX 用来发送 GET AJAX 请求
function sendAJAX(url){ return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.responseType = 'json'; xhr.open("GET", url); xhr.send(); //处理结果 xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ //判断成功 if(xhr.status >= 200 && xhr.status < 300){ //成功的结果 resolve(xhr.response); }else{ reject(xhr.status); } } } }); }
-
发送请求
sendAJAX('https://api.apiopen.top/getJok') .then(value => { console.log(value); }, reason => { console.warn(reason); });
-
-
Promise的状态改变
-
pending变为resolved (fulfilled)
-
pending变为rejected
说明:只有这两种,且一个promise对象只能改变一次状态,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的结果数据一般称为reason.
-
-
Promise.resolve方法:(value)=>{}
value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
-
Promise.reject方法:(reason)=>{}
reason:失败的原因
说明:返回一个失败的promise对象
-
Promise.all方法:(promises)=>{}
promise:包含n个promise的数组
说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就会失败
-
Promise.race方法:(promises)=>{}
promise:包含n个promise的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
-
修改Promise的状态
- resolve(value):如果当前是pending就会变为resolved(fulfilled)
- reject(reason):如果当前是pending就会变为rejected
- 抛出异常:如果当前是pending就会变为rejected
-
promise.then()返回的新 promise 的结果状态由什么决定
- 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
- 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
- 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
let p = new Promise((resolve, reject) => {
resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
// console.log(value);
//1. 抛出错误
// throw '出了问题';
//2. 返回结果是非 Promise 类型的对象
// return 521;
//3. 返回结果是 Promise 对象
// return new Promise((resolve, reject) => {
// // resolve('success');
// reject('error');
// });
}, reason => {
console.warn(reason);
});
console.log(result);
-
promise 异常传透
- 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
- 办法: 在回调函数中返回一个 pendding 状态的 promise 对象
-
中断 promise 链
有且只有一个方式 这里将Promise的状态设置为默认状态pending
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
console.log(111);
// 有且只有一个方式 这里将Promise的状态设置为默认状态pending
return new Promise((resolve,reject)=>{});
}).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});