Promise介绍及相关应用

124 阅读4分钟
1. 什么是Promise
  • Promise是ES6提出的一种解决JS中进行异步编程的解决方案;
  • Promise是一个对象,可以按照他的意思理解为是一个承诺,许诺过段时间会给出一个结果;
  • Promise的构造函数接收函数作为参数,传入resolve,reject作为参数,分别表示异步操作执行成功后的回调函数和异步操作执行失败了的回调函数;
2. Promise的三种状态
  • 初始状态 => pending
  • 已解决(调用了resolve函数):resolved/fulfilled
  • 已拒绝(调用了reject函数):rejected(若rejected状态下在后续.catch中对错误进行处理后状态会转变为fulfilled)
let i = 0;
function getJSON() {
  return new Promise((res, rej) => {
    if (i === 1) rej();
    res(i++);
  })
}

let p = new Promise(() => { });
console.log(p); // 状态为 pending
let p1 = new Promise((resolve, reject) => { resolve(); });
console.log(p1); // 状态为 fulfilled
console.log('=======前方高能=========')
let p2 = new Promise((resolve, reject) => { reject(); });
console.log(p2); // 状态为 rejected 

image.png

在p2对象后面可以调用.catch方法处理错误

let p2 = new Promise((resolve, reject) => { reject(); })
.catch(err => {
  console.log('err');
}) 
console.log(p2); // .catch处理过以后状态转变 rejected => fulfilled

image.png

3. Promise实例方法
3.1 Promise.prototype.then()
  • then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法.
const data = {
  name: 'sss',
  age: 18
}

new Promise((resolve => {
  resolve(data)
}))
.then(res => {
    console.log('data', data)  // {name: 'sss', age: 18}
    return data.name;
  })
  .then(name => {
    console.log('name', name) // name sss
  })
  • 上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作 为参数,传入第二个回调函数;
3.2 Promise.prototype.catch()
  • Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数
  • Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会 被下一个catch语句捕获
let p1 = new Promise((resolve, reject) => {
  reject('err')
})
  .catch(err => {
    console.log('err'); // err
  })
3.3 Promise.prototype.finally()
  • finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区 别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行.
let p1 = new Promise((resolve, reject) => {
  resolve('aaa');
  // reject('err')
})
  .finally(() => {
    console.log('最终执行') // 最终执行
  })
3.4 promise链式玩法
  • 通过在then方法中返回一个包含后续异步的Promise实例即可在外层.then获取其返回值
let p1 = new Promise((resolve, reject) => {
  resolve('aaa');
  // reject('err')
})
  .catch(err => {
    console.log('err');
  }) // 处理过以后fulfilled
  .then(res => {
    console.log('res:', res);
    return 1111111; // result
  }) // 处理过以后fulfilled
  .then(res2 => {
    console.log('res2', res2);
  })
  .finally(() => {
    console.log('最终执行')
  })
4. promise静态方法
4.1 Promise.all()
  • Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例
  • 如果多个请求,任意一个失败,则失败,保证全成功
function req() {       // 去解决,拒绝
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 数据回来了
      let data = Math.random();
      console.log('数据是:', data)
      if (data < 0.6) return reject(data)
      else return resolve(data); // 调用20行的参数,函数

    }, 1000);
  })
}

// 如果多个请求,任意一个失败,则失败,保证全成功
Promise.all([req(), req(), req()])
  // 全成功
  .then(resArr => {
    console.log('响应收据', resArr)
  })
  .catch(err => {
    console.log('失败了======');
  });
  • 只要三次调req()时有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
var p = Promise.all([p1,p2,p3]);
  • 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数
4.2 Promise.race()
  • Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例
var p = Promise.race([p1,p2,p3]);
  • 只要调用时传入的实例之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数
4.3 Promise.resolve()
  • Promise.resolve()将现有对象转为Promise对象
Promise.resolve('js');
//等价于
new Promise(resolve => resolve('js'))
  • 能够转化成为Promise对象的对象
  1. 参数是一个Promise实例
  2. 参数是一个thenable对象
  3. 参数不是具有then方法的对象,或根本就不是对象
  4. 不带有任何参数
4.4 Promise.reject()
  • Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected
  • Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数
var p = Promise.reject('error');
//等价于
var p = new Promise((resolve,reject) => reject('error'));