实现一个promise之完成对x的处理并测试

function resolvePromise(promise2, x, resolve, reject) { //如果promise和x是同一个对象,reject返回TypeError。 if(promise2 === x){ return reject(new TypeError('TypeError: Chaining cycle detected for promise #')); }; //如果被调用多次,只执行第一次,或略其它调用,如果x不是方法,是不会出现多次调用的。 let called = false; //如果x是对象或者方法 if((typeof x === 'object' && x !== null) || typeof x === 'function'){ //如果x是一个对象或者函数,取值then = x.then,如果x.then出错,抛出错误执行reject。 try{ let then = x.then; //如果then是一个方法,用call改变this指向,把resolve和reject当作参数传递。 // 成功参数y,失败参数r,并调用成功失败函数。 if(typeof then === 'function'){ then.call(x, (y) => { if(called) return; called = true; //如果return的是很多个promise,建议递归判断。 resolvePromise(promise2, 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); } }; 完成之后,promise官方推荐了一个测试方法,只有通过测试才算符合标准的promise: https://github.com/promises-aplus/promises-tests 全局安装promises-aplus-tests,然后写上下面的代码,最后执行promises-aplus-tests promise.js 全部通过就算完成了。 Promise.defer = Promise.deferred = function () { let dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }); return dfd; }; module.exports = Promise; 附上完成的代码,可以跑看看: const PENDING = 'PENDING'; const FULFILLED = 'FULFILLED'; const REJECTED = 'REJECTED'; //处理返回结果 function resolvePromise(promise2, x, resolve, reject) { if(promise2 === x){ return reject(new TypeError('TypeError: Chaining cycle detected for promise #')); }; let called = false; if((typeof x === 'object' && x !== null) || typeof x === 'function'){ try{ let then = x.then; if(typeof then === 'function'){ then.call(x, (y) => { if(called) return; called = true; resolvePromise(promise2, 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); } }; class Promise { constructor(executor){ this.state = PENDING; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; let resolve = (value) => { if(this.state === PENDING){ this.state = FULFILLED; this.value = value; this.onResolvedCallbacks.forEach(fn => fn()); } }; let reject = (reason) => { if(this.state === PENDING){ this.state = REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); } }; try{ executor(resolve, reject); }catch (e) { reject(e); } } then(onFulfilled, onRejected){ onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : y => y; onRejected = typeof onRejected === 'function' ? onRejected : r => {throw r}; let promise2 = new Promise((resolve, reject) => { if(this.state === FULFILLED){ setTimeout(() => { try{ let x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject) }catch (e) { reject(e); }; }, 0); }; if(this.state === REJECTED){ setTimeout(() => { try{ let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject) }catch (e) { reject(e); }; }, 0); }; if(this.state === PENDING){ this.onResolvedCallbacks.push(() => { setTimeout(() => { try{ let x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject) }catch (e) { reject(e); }; }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try{ let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject) }catch (e) { reject(e); }; }, 0); }); }; }); return promise2; } } Promise.defer = Promise.deferred = function () { let dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }); return dfd; }; module.exports = Promise; image

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):