详解promise

187 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第29天,点击查看活动详情

promise

Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。从语法上讲,Promise是一个对象,它可以获取异步操作的消息。提供了一个统一的API,各种异步操作都可以用同样的方法进行处理.

promise的三种状态

  • pending: 进行中
  • fulfilled: 已完成
  • reject: 已拒绝

其中这三种状态之间有两条关系线。只要达到其中一个终极状态,就不能改变了。

  1. Resolved: pending --> fulfiled
  2. Rejected: pending --> rejected

如下图: image.png

promise的方法

promise具有以下九种方法

  • then
  • catch
  • finally
  • all
  • race
  • allSettled
  • any
  • resolve
  • reject

1. Promise.prototype.then()

then()  方法返回一个 Promise。它最多需要有两个参数:Promise 的成功和失败情况的回调函数.

const promise1 = new Promise((resolve, reject) => {
  resolve('Success!');
  // reject('error!');
});

promise1.then((value) => {
  console.log(value); // "Success!"
}, (err) => {
  console.log(err);  // 'error!'
});

2. Promise.prototype.catch()

Promise对象的 **catch()**方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等价的 Promise对象,这可以允许链式调用其它 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected)`的一种简写形式。

let promise = new Promise(function(resolve, reject) {
  resolve('Success');
});

promise.then(function(value) {
  console.log(value); // "Success!"
  throw 'error!';  // 等价于 return Promise.reject('error!');
}).catch(function(e) {
  console.log(e); // "error"
}).then(function(){
  console.log('捕获到了异常');
}, function () {
  console.log('你好呀');
});

3. Promise.prototype.finally()

finally()方法指定不管promise最后的状态如何,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。

let promise = new Promise(function(resolve, reject) {
  resolve('Success');
});

promise.then(function(value) {
  console.log(value); // "Success!"
  return Promise.reject('error!');
}).catch(function(e) {
  console.log(e); // "error!!"
}).then(function(){
  console.log('捕获到了异常');
}).finally(()=>{
  console.log('我是finall,不管promise结果如何我都要执行');
});

4. Promise.all()

该方法用于将多个 Promise 实例包装成一个新的 Promise 实例,方法接受一个数组作为参数,数组参数都是Promsie实例。

const p1 = new Promise((resolve, reject) => {
    resolve('hello');
})
.then(result => result);
const p2 = new Promise((resolve, reject) => {
    throw new Error('报错了');
})
.then(result => result);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));//Error:报错了

5. Promise.race()

该方法同样是将多个 Promise 实例包装成一个新的 Promsie 实例,该方法与 Promise.all()方法一样,区别是该方法中只要参数之中有一个实例率先改变状态,该方法的实例状态跟着改变,那个率先改变的 Promise 实例的返回值就传递给该方法实例的回调函数。

const p = Promise.race([
    fetch('./index.js'),
    new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
    })
]);
p.then(console.log).catch(console.error);

6. Promise.allSettled()

该方法用来确定一组异步是否都结束(不管成功或失败)。方法接受一个数组作为参数,只有当参数数组中所有 Promise对象 都发生变化,返回的 Promise 对象才会发生状态变更。

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
    console.log(results);
});

7. Promise.any()

Promise.any()和Promise.race()方法很像,唯一区别就是Promise.any()不会因为某个 Promise 变成 rejected 状态而结束,必须等到所有参数 Promise 变成 rejected 状态才会结束。

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const alsoRejected = Promise.reject(Infinity);
Promise.any([resolved, rejected, alsoRejected]).then(function (result) {
  console.log(result); // 42
});
Promise.any([rejected, alsoRejected]).catch(function (results) {
  console.log(results instanceof AggregateError); // true
  console.log(results.errors); // [-1, Infinity]
});

8. Promise.resolve()

该方法能够将现有对象转换为 Promise 对象。

Promise.resolve('foo')
// 相当于
new Promise(resolve => resolve('foo'))

9. Promise.reject()

返回一个带有拒绝原因的 Promise 对象。

Promise.reject(new Error('fail')).then(() => {
}, (error) => {
  console.error(error);
});