1. Promise源码
isPromise函数
function isPromise(value) { if((typeof value === 'object' && value !== null) || typeof value === 'function') { return typeof value.then === 'function' } return false; } module.exports = isPromise;
resolvePromise函数
function resolvePromise(promise, x, resolve, reject) { if(x === promise) { return reject(new TypeError(`Chaining cycle detected for promise #<Promise>`)); } /** * 判断是否是promise有三个条件 * 1.是对象,且不是null * 2.是函数 * 3.满足1,2其中一个的基础上,有then属性,且是个函数 */ if((typeof x === 'object' && x !== null) || typeof x === 'function') { // 确保即使x是他人自定义的promise对象时,状态改变也只执行一次 let called; try { // 如果then属性通过getter定义 let then = x.then; if (typeof then === 'function') {// 是promise // then方法调用时绑定this,否则可能会导致this指向变更; 第二个参数成功回调 then.call(x, y => { if(called) return; called = true; // y仍然可能是promise resolvePromise(promise, y, resolve, reject); }, r => {//失败回调 if(called) return; called = true; reject(r); }) } else { resolve(x); } } catch (e) { if(called) return; called = true; reject(e); } } else { // 普通值 resolve(x); } } module.exports = resolvePromise;
Promise源码
/** * 1. Promise实例化时有个执行器函数,会立即执行 * 2. 执行器有两个方法,第一个是resolve, 第二个是reject * 3. promise实例有三种状态,pending, fulfilled, rejected * 默认是pending, 调用resolve后变为fulfilled; 调用reject后变为rejected * 4. 状态不可逆, 只能pending->fulfilled, 或者pending -> rejected * 5. 每个promise实例都有个then方法,then方法有两个参数, * 第一个是成功回调onFulfilled,第二个是失败回调onRejected * 6. 执行器的resolve函数会触发成功回调onFulfilled, * 执行器的reject函数或者throw触发失败回调onRejected * 7. then方法返回的是一个promise对象。 * 8. 每个promise对象都有catch方法。 * 9. Promise类(构造函数)有静态方法Promise.resolve(value)/Promise.reject(value) * 10. Promise类(构造函数)有静态方法Promise.all([...])返回一个promise实例 * 解决异步任务并发的问题,返回结果数组按照异步任务的顺序返回 */ const PENDING = 'PENDING'; const FULFILLED = 'FULFILLED'; const REJECTED = 'REJECTED'; const resolvePromise = require('./resolvePromise'); const isPromise = require('./isPromise'); class Promise { constructor(executor) { this.value; this.reason; this.status = PENDING; this.onResolvedCallbacks=[]; // then成功回调队列 this.onRejectedCallbacks=[]; // then失败回调队列 let resolve = (value) => { // resolve的值如果是promise, 则一直取值直到非promise为止 if (value instanceof Promise) { value.then(resolve, reject); } else if(this.status === PENDING) { this.status = FULFILLED; this.value = value; if (this.onResolvedCallbacks.length > 0) { this.onResolvedCallbacks.forEach(fn => fn()); } } } let reject = (reason) => { if(this.status === PENDING) { this.status = REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()) } } try{ executor(resolve, reject); } catch(err) { reject(err) } } then(onFulfilled, onRejected) {// 两个回调函数,都是可选参数 // 当参数不是回调函数或者省略时,赋予默认回调函数,将值向后传递 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val; onRejected = typeof onRejected === 'function' ? onRejected : e => {throw e}; // 返回promise可以实现链式调用 const promise = new Promise((resolve, reject) => { if(this.status === FULFILLED) { //微任务,等到new实例完成之后,获取返回的promise;否则promise未定义 process.nextTick(() => { try { let x = onFulfilled(this.value); // x有可能是promise对象,则需要继续处理,直至返回的是普通数据(非异常和promise) resolvePromise(promise, x, resolve, reject); } catch (e) { reject(e); } }) } if(this.status === REJECTED) { process.nextTick(() => { try { let x = onRejected(this.reason); resolvePromise(promise, x, resolve, reject); } catch (e) { reject(e) } }) } if(this.status === PENDING) { this.onResolvedCallbacks.push(() => { process.nextTick(() => { try { let x = onFulfilled(this.value); resolvePromise(promise, x, resolve, reject); } catch (e) { reject(e); } }) }) this.onRejectedCallbacks.push(() => { process.nextTick(() => { try { let x = onRejected(this.reason); resolvePromise(promise, x, resolve, reject); } catch(e) { reject(e); } }) }) } }) return promise; } catch(errCallback) { return this.then(null, errCallback); } finally(callback) { return this.then((value) => { return Promise.resolve(callback()).then(() => value) }, (err) => { return Promise.resolve(callback()).then(() => {throw err}) }) } } Promise.resolve = (value) => { if(isPromise(value)) { return value; } return new Promise((res,rej) => { res(value); }) } Promise.reject = (reason) => { if(isPromise(reason)) { return reason; } return new Promise((resolve,reject) => { reject(reason); }) } Promise.all = ( promises) => { // 处理并发;promises的数组中可以不是promise return new Promise((resolve,reject) => { let arr = [];// 存储promise的结果 let index = 0; //确保每个promise项都执行过 let processData = (i, data) => { arr[i] = data; if (++index === promises.length) { resolve(arr); } } for(let i=0; i<promises.length; i++) { let current = promises[i]; if(isPromise(current)) { current.then((data) => { processData(i, data); }, reject); //只要有一个reject状态就变rejected } else { processData(i, current); } } }) } Promise.race = (promises) => { return new Promise((resolve, reject) => { for(let i=0; i< promises.length; i++) { let current = promises[i]; if(isPromise(current)) { current.then(resolve, reject) } else { resolve(current); } } }) } // 测试Promise是否符合规范 Promise.deferred = function() { let dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }) return dfd; } module.exports = Promise;
2. 测试是否符合规范
1.全局安装测试命令工具
npm install promises-aplus-tests -g
2. 在代码中添加
// 测试Promise是否符合规范 Promise.deferred = function() { let dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }) return dfd; }
3. 使用命令工具测试
promises-aplus-tests promise.js