Promise系列(二)

90 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

前情回顾

上一篇中,我们认识了一下Promise是什么,他的基本用法。这一篇我们就接着介绍Promise的几个API

Promise.prototype.then()

  • then方法是定义在原型对象Promise.prototype上的
  • 作用是为Promise实例添加状态改变时的回调函数。
  • then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数。
  • then方法返回的时候一个新的Promise实例。因此可以采用链式写法。
const getJson = function (url) {
    return new Promise((resolve, reject) => {
      if (url === "posts.json") {
        resolve("posts.json")
      } else {
        reject("not posts.json")
      }
    })
  }
  getJson("posts.json").then(res => {
    // return res + "第一个then调用"  //posts.json第一个then调用
    return getJson(res)
  }).then(res => {
    console.log(res);
  })
  //posts.json

Promise.prototype.catch()

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

p.then((val) => console.log('fulfilled:', val))
 .catch((err) => console.log('rejected', err));

// 等同于
p.then((val) => console.log('fulfilled:', val))
 .then(null, (err) => console.log("rejected:", err));

Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

new Promise((resolve, reject) => {
    resolve(1)
  }).then(res => {
    return res += 1
  }).then(res => {
    if (res == 1) {
      return res
    } else {
      throw new Error("错误")
    }
  }).then(res => {
    console.log(res);
  }).catch(err => {
    console.log(err);
  })
  //Error:错误

一般总是建议,Promise 对象后面要跟catch()方法,这样可以处理 Promise 内部发生的错误。catch()方法返回的还是一个 Promise 对象,因此后面还可以接着调用then()方法。

const promise = function () {
    return new Promise((resolve, reject) => {
      resolve(x + 2)
    })
  }
  promise().catch(err => {
    console.log("error:",err);
  }).then(() => {
    console.log("这里也执行了");
  })
  //error: ReferenceError: x is not defined
  //这里也执行了

Promise.prototype.all()

  • Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3])
  • Promise.all()方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
  • p的状态是由p1,p2这些参数决定的。 (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2) 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

  • 如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
const p1 = new Promise((resolve, rejeect) => {
    resolve("hello")
  })
    .then(res => console.log(res))
    .catch(err => console.log(err))
    
  const p2 = new Promise((resolve, rejeict) => {
    throw new Error("error")
  })
    .then(res => console.log(res))
    .catch(err => console.log(err + ":p2错误"))
    
  Promise.all([p1, p2])
    .then(res => console.log(res))  //[undefined, undefined]
    .catch(err => console.log(err + ":all错误"))
    
    
    //hello
    //Error:error:p2错误
    //[undefined, undefined]
    ```