Promise原理讲解 && 实现一个Promise对象 (遵循Promise/A+规范)
面试精选之Promise

搞懂这两篇文章就差不离了

Promise 的使用

promise是一个构造函数,new Promise()返回一个promise对象,构造方法接受一个excutor函数作为参数,
excutor函数包含resolve和reject两个参数

  1. const promise = new Promise((resolve, reject) => {
  2. // 异步处理
  3. // 处理结束后、调用resolve 或 reject
  4. });

Promise相当于一个状态机

有三种状态:
pending:promise对象初始化的状态
fulfilled:当调用resolve(成功),会由pending => fulfilled
rejected:当调用reject(失败),会由pending => rejected

promise对象方法

then

then方法注册 当resolve(成功)/reject(失败)的回调函数

  1. // onFulfilled 是用来接收promise成功的值
  2. // onRejected 是用来接收promise失败的原因
  3. promise.then(onFulfilled, onRejected);

注意:then方法是异步执行的

resolve

resolve(成功) onFulfilled会被调用

  1. const promise = new Promise((resolve, reject) => {
  2. resolve('fulfilled'); // 状态由 pending => fulfilled
  3. });
  4. promise.then(result => { // onFulfilled
  5. console.log(result); // 'fulfilled'
  6. }, reason => { // onRejected 不会被调用
  7. })

reject(失败) onRejected会被调用

  1. const promise = new Promise((resolve, reject) => {
  2. reject('rejected'); // 状态由 pending => rejected
  3. });
  4. promise.then(result => { // onFulfilled 不会被调用
  5. }, reason => { // onRejected
  6. console.log(reason); // 'rejected'
  7. })

catch

在链式写法中可以捕获前面then中发送的异常,

  1. promise.catch(onRejected)
  2. 相当于
  3. promise.then(null, onRrejected);
  4. // 注意
  5. // onRejected 不能捕获当前onFulfilled中的异常
  6. promise.then(onFulfilled, onRrejected);
  7. // 可以写成:
  8. promise.then(onFulfilled)
  9. .catch(onRrejected);

promise chain

promise.then方法每次调用 都返回一个新的promise对象 所以可以链式写法

  1. function taskA() {
  2. console.log("Task A");
  3. }
  4. function taskB() {
  5. console.log("Task B");
  6. }
  7. function onRejected(error) {
  8. console.log("Catch Error: A or B", error);
  9. }
  10. var promise = Promise.resolve();
  11. promise
  12. .then(taskA)
  13. .then(taskB)
  14. .catch(onRejected) // 捕获前面then方法中的异常
  1. /**
  2. then 的方法异常 下面的方法不在执行 直接走catch
  3. **/
  4. function taskA() {
  5. return new Promise((resolve,reject)=>{
  6. setTimeout(()=>{
  7. reject("Task A setTimeOut");
  8. },2000)
  9. })
  10. }
  11. function taskB(result) {
  12. console.log("Task B",result);
  13. }
  14. function onRejected(error) {
  15. console.log("Catch Error: A or B", error);
  16. }
  17. var promise = Promise.resolve(111);
  18. promise.then(async (result)=>{
  19. console.log("Task A start");
  20. await taskA()
  21. console.log("Task A end");
  22. })
  23. .then(taskB)
  24. .catch(onRejected) // 捕获前面then方法中的异常

图片.png

  1. function taskA() {
  2. return new Promise((resolve,reject)=>{
  3. setTimeout(()=>{
  4. resolve("Task A setTimeOut");
  5. },2000)
  6. })
  7. }
  8. function taskB() {
  9. console.log("Task B");
  10. }
  11. function onRejected(error) {
  12. console.log("Catch Error: A or B", error);
  13. }
  14. var promise = Promise.resolve(111);
  15. promise.then(async (result)=>{
  16. console.log("Task A start");
  17. console.log(await taskA())
  18. console.log("Task A end");
  19. })
  20. .then(taskB)
  21. .catch(onRejected) // 捕获前面then方法中的异常

图片.png

promise静态方法

Promise.resolve 返回一个fulfilled状态的promise对象

  1. Promise.resolve('hello').then(function(value){
  2. console.log(value);
  3. });
  4. Promise.resolve('hello');
  5. // 相当于
  6. const promise = new Promise(resolve => {
  7. resolve('hello');
  8. });

Promise.reject 返回一个rejected状态的promise对象

  1. Promise.reject(24);
  2. new Promise((resolve, reject) => {
  3. reject(24);
  4. });

Promise.all 接收一个promise对象数组为参数

只有全部为resolve才会调用 通常会用来处理 多个并行异步操作
值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1,P2

  1. const p1 = new Promise((resolve, reject) => {
  2. resolve(1);
  3. });
  4. const p2 = new Promise((resolve, reject) => {
  5. resolve(2);
  6. });
  7. const p3 = new Promise((resolve, reject) => {
  8. resolve(3);
  9. });
  10. Promise.all([p1, p2, p3]).then(data => {
  11. console.log(data); // [1, 2, 3] 结果顺序和promise实例数组顺序是一致的
  12. }, err => {
  13. console.log(err);
  14. });

Promise.race 接收一个promise对象数组为参数

Promise.race 只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。
race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败

一般用于和定时器绑定,比如将一个请求和一个三秒的定时器包装成Promise实例,加入到race队列中,请求三秒中还没有回应时,给用户一些提示或一些相应的操作
图片.png

  1. const p1 = new Promise((resolve, reject) => {
  2. setTimeout(()=>{resolve("success")},1000)
  3. });
  4. const p2 = new Promise((resolve, reject) => {
  5. setTimeout(()=>{reject("fail")},500)
  6. });
  7. Promise.race([p1,p2]).then((result)=>{
  8. console.log(result)
  9. }).catch((err)=>{
  10. console.log(err)
  11. })