Promise对象
Promise
基本概念
- 译为“承诺”,这也就表达了将来会执行的操作,代表异步操作;
- 一共有三种状态,分别为 pending(进行中)、fulfilled(已成功)和 rejected(已失败)。
- 特点
- 只有异步操作可以决定当前处于的状态,并且任何其他操作无法改变这个状态;
- 一旦状态改变,就不会在变。状态改变的过程只可能是:从 pending 变为 fulfilled 和从 pending 变为 rejected。如果状态发生上述变化后,此时状态就不会在改变了,这时就称为 resolved(已定型)
- 与事件( Event )的区别:事件错过了的话再去监听,是得不到结果的。
- 缺点
- 无法取消 Promise,一旦新建它就会立即执行,无法中途取消;
- 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部;
- 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
- Promise 的出现主要是解决地狱回调的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了 Promise 我们就无需嵌套。
- promise 的本质是什么:分离异步数据获取和业务
基本用法
Promise 对象是由关键字 new 及其构造函数来创建的。
1 |
|
- 该构造函数接收两个函数作为参数,分别是 resolve 和 reject。
- 当异步操作执行成功后,会将异步操作结果作为参数传入 resolve 函数并执行,此时 Promise 对象状态从 pending 变为 fulfilled;
- 失败则会将异步操作的错误作为参数传入 reject 函数并执行,此时 Promise 对象状态从 pending 变为 rejected;
通过 then 方法,分别指定 resolved 状态和 rejected 状态的回调函数。
1 |
|
- then 方法可以接收两个回调函数作为参数,第一个回调函数就是 fulfilled 状态时调用;
- 第二个回调函数就是 rejected 时调用。这边的第二个参数是可选的,不一定要提供。
方法
Promise.resolve(value)
返回一个以给定的值解析后的 Promise 对象;
参数 value 主要有以下几种情况:
一个 Promise 实例
原封不动的返回该实例;1
2
3
4
5
6
7
8
9var original = Promise.resolve("我在第二行");
var cast = Promise.resolve(original);
cast.then(function (value) {
console.log("value: " + value);
});
console.log("original === cast ? " + (original === cast));
// "original === cast ? true"
// "value: 我在第二行"一个 thenable 对象:是指含有 then 方法的对象
跟随这个 thenable 对象的,采用它的最终状态;1
2
3
4
5
6
7
8
9
10
11
12
13let thenable = {
then: function (resolve, reject) {
resolve(42);
},
};
let p = Promise.resolve(thenable);
p.then(function (value) {
console.log(value);
});
// 42普通数据:[String|Array|Object|Number]
直接将传入参数当最终结果并返回一个新的 Promise;1
2
3
4
5
6let p = Promsie.resolve(123);
p.then(function (num) {
console.log(num);
});
// 123无参数
直接返回一个 resolved 状态的 Promise 对象1
2
3
4let p = Promsie.resovle();
p.then(function () {
// do something here...
});
Promise.reject(reason)
- 参数:表示被拒绝的原因;
传入的参数会原封不动的作为 reject 函数的理由,并不会因为传入的参数 Promise 或者是 thenable 对象而有所不同 - 返回值:一个含有 reason 的状态为 rejected 的 Promise
promise.all()
- Promise.all()方法将多个 Promise 实例包装成一个 Promise 对象(p),接受一个数组(p1,p2,p3)作为参数,数组中不一定需要都是 Promise 对象,但是一定具有 Iterator 接口,如果不是的话,就会调用 Promise.resolve 将其转化为 Promise 对象之后再进行处理。
- 使用 Promise.all()生成的 Promise 对象(p)的状态是由数组中的 Promise 对象(p1,p2,p3)决定的。
- 如果所有的 Promise 对象(p1,p2,p3)都变成 fullfilled 状态的话,生成的 Promise 对象(p)也会变成 fullfilled 状态,p1,p2,p3 三个 Promise 对象产生的结果会组成一个数组返回给传递给 p 的回调函数。
- 如果 p1,p2,p3 中有一个 Promise 对象变为 rejected 状态的话,p 也会变成 rejected 状态,第一个被 rejected 的对象的返回值会传递给 p 的回调函数。
- Promise.all()方法生成的 Promise 对象也会有一个 catch 方法来捕获错误处理,但是如果数组中的 Promise 对象变成 rejected 状态时,并且这个对象还定义了 catch 的方法,那么 rejected 的对象会执行自己的 catch 方法。并且返回一个状态为 fullfilled 的 Promise 对象,Promise.all()生成的对象会接受这个 Promise 对象,不会返回 rejected 状态。
Promise 原型
Promise.prototype.then()
- Promise 的实例具有 then 方法,主要作用是为 Promise 实例发生状态改变时添加回调函数。
- 它接收两个回调函数作为参数,第一个参数是 fulfilled 状态时的回调函数;第二个参数是 rejected 状态时的回调函数,可不传入。
- 并且该方法返回一个新的 Promise 对象。
1 |
|
Promise.prototype.catch()
返回一个 Promise,并且处理拒绝的情况。它的行为与调用 Promise.prototype.then(undefined, onRejected)相同。
1 |
|
推荐使用 catch 方法,不要在 then 方法中定义 rejected 状态的回调函数;这是因为使用 catch 还可以捕获在 then 方法执行中存在的错误。
1 |
|
Promise.prototype.finally()
返回一个 Promsie。是指,在上一轮 promise 运行结束后,无论 fulfilled 还是 rejected,都会执行指定的回调函数。
该方法适合,无论结果如何都要进行的操作,例如清除数据。
语法:该回调函数的不接受任何参数;
1
p.finally();
例子
axios 与 Promise 异步调用接口获取数据:
1 |
|