实现PromiseA+

代码实现

const PENDING = 'pending';
const RESOLVED = 'resolve';
const REJECTED = 'rejected';

function Promise (execute) {
 const self = this;
 self.status = PENDING;
 self.value = undefined;
 self.reason = undefined;

 self.onFulfilledCallbacks = []
 self.onRejectCallbacks = [];

 function resolve (val) {

   setTimeout(() => {
     if (self.status === PENDING) {
       self.status = RESOLVED;
       self.value = val;
       self.onFulfilledCallbacks.forEach(fn => fn());
     }
   }, 0)

 }

 function reject (reason) {
   setTimeout(() => {
     if (self.status === PENDING) {
       self.status = REJECTED;
       self.reason = reason;
       self.onRejectCallbacks.forEach(fn => fn());
     }
   }, 0)

 }

 try {
   execute(resolve, reject)
 } catch (e) {
   reject(e);
 }

}

Promise.prototype.then = function (onFulfilled, onRejected) {
 let self = this;
 let promise2;

 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (v) {
   return v
 };
 onRejected = typeof onRejected === 'function' ? onRejected : err => {
   throw err
 };

 return promise2 = new Promise((resolve, reject) => {
   if (self.status === RESOLVED) {
     setTimeout(() => {
       try {
         let x = onFulfilled(self.value);
         promiseResolutionProcedure(promise2, x, resolve, reject);
       } catch (err) {
         return reject(err)
       }
     }, 0)

   } else if (self.status === REJECTED) {
     setTimeout(() => {
       try {
         let x = onRejected(self.reason);
         promiseResolutionProcedure(promise2, x, resolve, reject)
       } catch (err) {
         return reject(err)
       }
     }, 0)

   } else { // PENDING
     self.onFulfilledCallbacks.push(() => {
       setTimeout(() => {
         try {
           let x = onFulfilled(self.value);
           promiseResolutionProcedure(promise2, x, resolve, reject)
         } catch (e) {
           reject(e)
         }
       }, 0)

     })

     self.onRejectCallbacks.push(() => {
       setTimeout(() => {
         try {
           let x = onRejected(self.reason);
           promiseResolutionProcedure(promise2, x, resolve, reject)
         } catch (e) {
           return reject(e)
         }
       }, 0)

     })
   }
 })


}
function promiseResolutionProcedure (promise2, x, resolve, reject) {
 if (promise2 === x) {
   return reject(new TypeError('循环引用'));
 }

 let called;
 if (x instanceof Promise) {
   if (x.status === PENDING) {
     x.then((val) => {
       // resolve(val)
       promiseResolutionProcedure(promise2, val, resolve, reject)
     }, (e) => {
       reject(e);
     })
   } else {
     x.then(resolve, reject);
   }
 }


 if (x != null && ((typeof x === 'function') || (typeof x === 'object'))) {
   try {
     let then = x.then;
     if (typeof then === 'function') {
       then.call(x, (y) => {
         if (called) return;
         called = true;
         promiseResolutionProcedure(promise2, y, resolve, reject);
       }, (err) => {
         if (called) return;
         called = true;
         reject(err);
       })
     } else {
       resolve(x);
     }
   } catch (e) {
     if (called) return;
     called = true;
     reject(e);
   }
 }
 else {
   return resolve(x);
 }
}

Promise.defer = Promise.deferred = function () {
 let dfd = {};
 dfd.promise = new Promise((resolve, reject) => {
   dfd.resolve = resolve;
   dfd.reject = reject;
 });
 return dfd;
}

module.exports = Promise;


var pro = new Promise((resolve, reject) => {
 resolve(123)
})

pro.then(null, null).then(data => {
 console.log(data)
})

promiseA+规范参考

https://promisesaplus.com/

Promise测试 脚本

1. 安装

npm install -g promises-aplus-tests

2. 测试

promises-aplus-tests promise.js

你可能感兴趣的:(实现PromiseA+)