Promise

76 阅读4分钟

一. Promise三个实例方法:then、catch、finally

  • 第一种::then() 可能有两种结果,第一个函数是成功时的回调,第二个函数是失败时的回调。
  • 第二种:catch()每一步then都写第二个回调参数特别麻烦,为了简化用catch铺获上面多个then产生的异常。
  • 第三种:finally()在 promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数。
const promise = new Promise((resovle, reject) => {
  if (true) {
    resovle("成功");
  } else {
    reject("失败");
  }
});
//第一种:两种结果的写法
promise
  .then(
    (res) => {
      console.log(res);
      return `第二个${res}`;
    },
    (err) => {
      console.log(err);
      return `第二个${err}`;
    }
  )
  .then(
    (res) => console.log(res),
    (err) => console.log(err)
  );
  
//第二种:catch铺获reject异常
promise
  .then((res) => {
    console.log(res);
    return `第二个${res}`;
  })
  .then((res) => console.log(res))
  .catch((err) => console.log(err));
//第三种finally
  promise
  .then((res) => {
    console.log(res);
    return `第二个${res}`;
  })
  .then((res) => console.log(res))
  .catch((err) => console.log(err))
  .finally(() => {
    console.log('不管成功或者失败我都会执行');
  });

二. Promise六个静态方法:Promise.all()Promise.allSettled()Promise.any()Promise.race()Promise.resolve()Promise.reject()

  1. Promise.all()中的Promise序列会全部执行通过才认为是成功,并按顺序以数组形式返回,否则认为是失败,如下面例子;
    当需要处理多个Promise并行时,大多数情况下Promise.all()用起来是非常顺手的,可是一旦有一个promise出现了异常,被reject了,情况就会变的麻烦,如下第二种情况;
    尽管能用catch捕获其中的异常,但你会发现其他执行成功的Promise的消息都丢失了,仿佛石沉大海一般
    要么全部成功,要么全部重来,这是Promise.all()本身的强硬逻辑,也是痛点的来源,不能说它错,但这的确给Promise.allSettled()留下了立足的空间

(1)第一种都成功

function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("我是A--成功");
    }, delay);
  });
}
function B(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("我是B--成功");
    }, delay);
  });
}
Promise.all([A(1000), B(4000)])
  .then((res) => {
    console.log("Promise.all--成功====", res);
    //4秒钟后返回。Promise.all--成功==== [ '我是A--成功', '我是B--成功' ]
  })
  .catch((err) => {
    console.log("Promise.all--err====", err);
  });

(1)第二种有一个失败

function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("我是A--成功");
    }, delay);
  });
}
function B(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
       reject("我是B--失败");
    }, delay);
  });
}
Promise.all([A(1000), B(4000)])
  .then((res) => {
    console.log("Promise.all--成功====", res);
  })
  .catch((err) => {
    console.log("Promise.all--err====", err);
    //4秒钟后返回。Promise.all--err==== 我是B--失败
  });
  1. Promise.allSettled()所有promise的数据都被包含在then语句中,且每个promise的返回值多了一个status字段,表示当前promise的状态,没有任何一个promise的信息被丢失。
    因此,当用Promise.allSettled()时,我们只需专注在then语句里,当有promise被异常打断时,我们依然能妥善处理那些已经成功了的promise,不必全部重来
function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("我是A--成功");
    }, delay);
  });
}
function B(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("我是B--失败");
    }, delay);
  });
}
Promise.allSettled([A(1000), B(4000)]).then((res) => {
  console.log("Promise.allSettled--成功====", res);
  //4秒钟后返回
  //Promise.allSettled--成功==== [
  //   { status: 'fulfilled', value: '我是A--成功' },
  //   { status: 'rejected', reason: '我是B--失败' }
  // ]
});
  1. Promise.any()只要其中的一个 promise 成功,就立刻返回那个已经成功的 promise无需等待其他promise结果。如下第一种例子:
    如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和 AggregateError 类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起,如下第一种例子:

第一种

function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("我是A--成功");
    }, delay);
  });
}
function B(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("我是B-失败");
    }, delay);
  });
}
Promise.any([A(1000), B(4000)])
  .then((res) => {
    console.log("Promise.any--成功====", res);//1秒钟返回:Promise.any--成功==== 我是A--成功
  })
  .catch((err) => {
    console.log("Promise.any--失败====", err);
  });

第二种

function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("我是A--失败");
    }, delay);
  });
}
function B(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("我是B-失败");
    }, delay);
  });
}
Promise.any([A(1000), B(4000)])
  .then((res) => {
    console.log("Promise.any--成功====", res);
  })
  .catch((err) => {
    console.log("Promise.any--失败====", err);
    //4秒钟后返回
    // Promise.any--失败==== [AggregateError: All promises were rejected] {
    //     [errors]: [ '我是A--失败', '我是B-失败' ]
    //   }
  });
  1. Promise.race()任意一个最快的返回的就立刻执行返回,不管成功还是失败
function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("我是A--失败");
    }, delay);
  });
}
function B(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("我是B-失败");
    }, delay);
  });
}
Promise.race([A(1000), B(4000)])
  .then((res) => {
    console.log("Promise.race--成功====", res);
  })
  .catch((err) => {
    console.log("Promise.race--失败====", err);//1秒钟返回:Promise.race--失败==== 我是A--失败
  });
  1. Promise.resolve() 认为是new Promise()方法的快捷方式
    等价写法:Promise.resolve('foo')<==>new Promise(resolve => resolve('foo'))
    Promise.resolve()可接收4种参数
    (1)参数是一个promise实例;
    (2)参数是thenable对象(thenable对象指的是具有then方法的对象);
    (3)参数不是具有then方法的对象,或根本就不是对象;
    (4)不带有任何参数;
function A(delay) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("我是A--成功");
    }, delay);
  });
}
let thenable = {
  then: function (resolve, reject) {
    resolve(39);
  }
};
Promise.resolve(A(1000)).then((res) => console.log("成功:", res)); //成功: 我是A--成功
Promise.resolve(thenable).then((res) => console.log("thenable成功:", res)); //thenable成功: 39
Promise.resolve("hello world").then((res) => console.log("成功:", res));//成功: hello world
Promise.resolve().then((res) => console.log("成功:", res));//成功: undefined
  1. Promise.reject() 方法返回一个带有拒绝原因的 Promise 对象