Catalyst

JS 笔记:Promise

Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值。

构造一个 Promise

let p = new Promise((resolve, reject) => {
  setTimeout(() => resolve("1 秒后执行代码"), 1000);
});

p.then((data) => console.log(data));
//1 秒后执行代码

Promise有三种状态:

  • 初始状态 pending
  • 成功 fulfilled
  • 失败 rejected

一个完成前的控制台打印:

let p = new Promise((resolve, reject) => {
  setTimeout(() => resolve("1 秒后执行代码"), 1000);
});

console.log(p);
//Promise { <state>: "pending" }

p.then((data) => console.log(p));
//Promise { <state>: "fulfilled", <value>: "1 秒后执行代码" }

使用一个 Promise

  • 回调函数在本轮所有事件循环运行完成后执行。
  • 使用 catch 终止链以捕获异常。
  • 使用 finally 完成无论成功与否的后续操作。
let p1 = new Promise((resolve, reject) => {
  reject("fail");
});
p1.then((data) => console.log(data))
  .catch((e) => console.log(e))
  .finally(() => {
    console.log("finally");
  });
//fail
//finally

方法

Promise.all

方法返回一个Promise对象,所有参数里的promise都触发成功的时候才会成功,并将参数里所有promise的返回值数组作为成功回调的返回值,第一个失败的promise信息作为失败信息。

Promise.race

任意一个参数中的子promise返回结果后,将其结果返回。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("1 秒"), 1000);
});

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("2 秒"), 2000);
});

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("3 秒"), 2000);
});

Promise.race([p1, p2, p3]).then((data) => console.log(data));
//1 秒
Promise.all([p1, p2, p3]).then((data) => console.log(data));
//["1 秒", "2 秒", "3 秒"]

实现一个Promise.all

function myPromiseAll(parr) {
  let ans = [];

  return new Promise((resolve, reject) => {
    run(0);

    function run(i) {
      if (i < parr.length)
        return parr[i].then((data) => {
            ans.push(data);
            run(i + 1);
          }).catch((e) => reject(e));
      else resolve(ans);
    }
  });
}

/*测试*/
let p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("1 秒"), 1000);
});

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("2 秒"), 2000);
});

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("3 秒"), 3000);
});

let p4 = new Promise((resolve, reject) => {
  setTimeout(() => reject("错误"), 1000);
});

myPromiseAll([p1, p2, p3]).then((data) => console.log(data));
//["1 秒", "2 秒", "3 秒"]
myPromiseAll([p1, p2, p4])
  .then((data) => console.log(data))
  .catch((e) => console.log(e));
//错误

实现一个Promise.race

function myPromiseRace(parr) {
  return new Promise((resolve, reject) => {
    for (let p of parr) p.then((data) => resolve(data)).catch((e) => reject(e));
  });
}

/*测试*/
let p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("1 秒"), 1000);
});

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("2 秒"), 2000);
});

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("3 秒"), 3000);
});

let p4 = new Promise((resolve, reject) => {
  setTimeout(() => reject("错误"), 1000);
});

myPromiseRace([p3, p2, p1]).then((d) => console.log(d));
//1 秒
myPromiseRace([p2, p3, p4])
  .then((d) => console.log(d))
  .catch((e) => console.log(e));
//错误

参考: