- // 三种状态
- const PENDING = "pending";
- const RESOLVED = "resolved";
- const REJECTED = "rejected";
- // promise 接收一个函数参数, 该函数会立即执行
- function MyPromise(fn) {
- let _this = this;
- _this.currentState = PENDING;
- _this.value = undefined;
- // 用于保存 then 中的回调, 只有当 promise
- // 状态为 pending 时才会缓存, 并且每个实例至多缓存一个
- _this.resolvedCallbacks = [];
- _this.rejectedCallbacks = [];
- _this.resolve = function(value) {
- if (value instanceof MyPromise) {
- // 如果 value 是个 Promise, 递归执行
- return value.then(_this.resolve, _this.reject)
- }
- setTimeout(() =>{ // 异步执行, 保证执行顺序
- if (_this.currentState === PENDING) {
- _this.currentState = RESOLVED;
- _this.value = value;
- _this.resolvedCallbacks.forEach(cb =>cb());
- }
- })
- };
- _this.reject = function(reason) {
- setTimeout(() =>{ // 异步执行, 保证执行顺序
- if (_this.currentState === PENDING) {
- _this.currentState = REJECTED;
- _this.value = reason;
- _this.rejectedCallbacks.forEach(cb =>cb());
- }
- })
- }
- // 用于解决以下问题
- // new Promise(() => throw Error('error))
- try {
- fn(_this.resolve, _this.reject);
- } catch(e) {
- _this.reject(e);
- }
- }
- MyPromise.prototype.then = function(onResolved, onRejected) {
- var self = this;
- // 规范 2.2.7,then 必须返回一个新的 promise
- var promise2;
- // 规范 2.2.onResolved 和 onRejected 都为可选参数
- // 如果类型不是函数需要忽略, 同时也实现了透传
- // Promise.resolve(4).then().then((value) => console.log(value))
- onResolved = typeof onResolved === ' function' ? onResolved: v =>v;
- onRejected = typeof onRejected === ' function' ? onRejected: r =>
- throw r;
- if (self.currentState === RESOLVED) {
- return (promise2 = new MyPromise(function(resolve, reject) {
- // 规范 2.2.4, 保证 onFulfilled,onRjected 异步执行
- // 所以用了 setTimeout 包裹下
- setTimeout(function() {
- try {
- var x = onResolved(self.value);
- resolutionProcedure(promise2, x, resolve, reject);
- } catch(reason) {
- reject(reason);
- }
- });
- }));
- }
- if (self.currentState === REJECTED) {
- return (promise2 = new MyPromise(function(resolve, reject) {
- setTimeout(function() {
- // 异步执行 onRejected
- try {
- var x = onRejected(self.value);
- resolutionProcedure(promise2, x, resolve, reject);
- } catch(reason) {
- reject(reason);
- }
- });
- }));
- }
- if (self.currentState === PENDING) {
- return (promise2 = new MyPromise(function(resolve, reject) {
- self.resolvedCallbacks.push(function() {
- // 考虑到可能会有报错, 所以使用 try/catch 包裹
- try {
- var x = onResolved(self.value);
- resolutionProcedure(promise2, x, resolve, reject);
- } catch(r) {
- reject(r);
- }
- });
- self.rejectedCallbacks.push(function() {
- try {
- var x = onRejected(self.value);
- resolutionProcedure(promise2, x, resolve, reject);
- } catch(r) {
- reject(r);
- }
- });
- }));
- }
- };
- // 规范 2.3
- function resolutionProcedure(promise2, x, resolve, reject) {
- // 规范 2.3.1,x 不能和 promise2 相同, 避免循环引用
- if (promise2 === x) {
- return reject(new TypeError("Error"));
- }
- // 规范 2.3.2
- // 如果 x 为 Promise, 状态为 pending 需要继续等待否则执行
- if (x instanceof MyPromise) {
- if (x.currentState === PENDING) {
- x.then(function(value) {
- // 再次调用该函数是为了确认 x resolve 的
- // 参数是什么类型, 如果是基本类型就再次 resolve
- // 把值传给下个 then
- resolutionProcedure(promise2, value, resolve, reject);
- },
- reject);
- } else {
- x.then(resolve, reject);
- }
- return;
- }
- // 规范 2.3.3.3.3
- // reject 或者 resolve 其中一个执行过得话, 忽略其他的
- let called = false;
- // 规范 2.3.3, 判断 x 是否为对象或者函数
- if (x !== null && (typeof x === "object" || typeof x === "function")) {
- // 规范 2.3.3.2, 如果不能取出 then, 就 reject
- try {
- // 规范 2.3.3.1
- let then = x.then;
- // 如果 then 是函数, 调用 x.then
- if (typeof then === "function") {
- // 规范 2.3.3.3
- then.call(x, y =>{
- if (called) return;
- called = true;
- // 规范 2.3.3.3.1
- resolutionProcedure(promise2, y, resolve, reject);
- },
- e =>{
- if (called) return;
- called = true;
- reject(e);
- });
- } else {
- // 规范 2.3.3.4
- resolve(x);
- }
- } catch(e) {
- if (called) return;
- called = true;
- reject(e);
- }
- } else {
- // 规范 2.3.4,x 为基本类型
- resolve(x);
- }
- }
来源: http://www.bubuko.com/infodetail-2973877.html