随笔 - 53  文章 - 1  评论 - 0  阅读 - 12299

简述ES6中的Promise对象

Promise 的含义

所谓Promise,行为上是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。语法上,Promise 是一个对象,它可以获取异步操作的消息。

  • Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),一旦状态改变,就不会再变。只有两种可能,从pending变为fulfilled和从pending变为rejected。

基本用法

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

then方法

  • then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
  • then方法返回的是一个新的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法。

catch方法

  • catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误(rejected状态或捕获的代码运行错误)时的回调函数。Promise 对象的错误具有“冒泡”性质。会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

finally方法

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。finally本质上是then方法的特例。

promise
.finally(() => {
  // 语句
});

// 等同于
promise
.then(
  result => {
    // 语句
    return result;
  },
  error => {
    // 语句
    throw error;
  }
);

具体实现

Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

Promise的实现

// 1. promise status状态不可逆
// 2. catch处理指定错误(rejected状态或捕获的代码运行错误)
// 3. then返回的是promise,以实现链式调用

class MyPromise {
  constructor(executor) {
    this.status = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    const resolve = (value) => {
      if (this.status === 'pending') {
        this.status = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(fn => fn());
      }
    };
    const reject = (reason) => {
        this.status = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(fn => fn());
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      const fulfilled = () => {
        try {
          if (typeof onFulfilled === 'function') {
            resolve(onFulfilled(this.value));
          } else {
            resolve(this.value);
          }
        } catch (error) {
          reject(error)
        }
      };
      const rejected = () => {
        try {
          if (typeof onRejected === 'function') {
            resolve(onRejected(this.reason));
          } else {
            reject(this.reason);
          }
        } catch (error) {
          reject(error);
        }
      };
      switch (this.status) {
        case 'fulfilled':
          fulfilled();
          break;
        case 'rejected':
          rejected();
          break;
        default:
          this.onFulfilledCallbacks.push(() => fulfilled());  
          this.onRejectedCallbacks.push(() => rejected());  
      }
    });

  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }

  finally(cb) {
    this.then(() => cb(), () => cb());
  }
}
posted on   DJ荒野  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示