function MyPromise(executor) { // 初始化promise实例对象状态 this._status = 'pending'; // 初始化promise实例对象结果值 this._value = undefined;
// 初始化存储 回调函数 的容器 this._callbacks = {};
// 缓存this --> promise实例对象 const _that = this;
try { // 放置可能出错代码 // 一旦try里面代码出错了,就会中断try中代码运行,直接来到catch // 执行MyPromise构造函数,要立即执行executor executor(resolve, reject); } catch (e) { // 来到catch,说明executor函数内部出错了~ // 将promise对象状态改成rejected reject(e); }
// 定义resolve function resolve(value) { // 状态只能修改一次 if (_that._status === 'pending') { // 调用resolve方法将promise对象状态改成resolved状态 _that._status = 'resolved'; _that._value = value; // 异步调用onResolved函数 if (_that._callbacks.onResolved) { setTimeout(() => { _that._callbacks.onResolved(value) }) } } }
// 定义reject function reject(reason) { if (_that._status === 'pending') { // 调用reject方法将promise对象状态改成rejected状态 _that._status = 'rejected'; _that._value = reason; // 异步调用onRejected函数 if (_that._callbacks.onRejected) { setTimeout(() => { _that._callbacks.onRejected(reason) }) } } } }
MyPromise.prototype.then = function (onResolved, onRejected) { const _that = this;
// 如果onResolved存在,不变 // 如果onResolved不存在,说明catch触发的。 如果是成功状态promise,保证返回值还是一个成功状态promise onResolved = onResolved ? onResolved : (value) => value; // then方法一旦只传一个参数,并且是失败状态promise,保证返回值 是 失败状态promise内部的值 onRejected = onRejected ? onRejected : (reason) => { throw reason };
// 为了将来作为promise对象使用 let promise = null; // this指向promise实例对象 if (this._status === 'resolved') { // 说明promise对象的状态是resolved // 异步调用onResolved函数 promise = new MyPromise(function (resolve, reject) { setTimeout(() => { doResolve(onResolved, _that._value, resolve, reject); }) }) } else if (this._status === 'rejected') { promise = new MyPromise(function (resolve, reject) { setTimeout(() => { doResolve(onRejected, _that._value, resolve, reject); }) }) } else { // 说明promise对象的状态是pending状态 // 将回调函数存在this上 promise = new MyPromise(function (resolve, reject) { // _that是p1, 外面promise是p2 // p1调用onResolved/onRejected回调时,要更新p2的状态 _that._callbacks.onResolved = function (value) { doResolve(onResolved, value, resolve, reject); }; _that._callbacks.onRejected = function (reason) { doResolve(onRejected, reason, resolve, reject); }; }) } // 为了链式调用 return promise; }
// 定义函数复用代码 function doResolve(onFn, value, resolve, reject) { try { const result = onFn(value); if (result instanceof MyPromise) { result.then(resolve, reject) } else { resolve(result); } } catch (e) { reject(e); } }
MyPromise.prototype.catch = function (onRejected) { return this.then(undefined, onRejected); }
MyPromise.prototype.finally = function (onResolved) { const _that = this; return new Promise((resolve, reject) => { if (_that._status === 'pending') { const callback = function (value) { doResolve(onResolved, value, resolve, reject) }; _that._callbacks.onResolved = callback; _that._callbacks.onRejected = callback; } else { doResolve(onResolved, _that._value, resolve, reject); } }) }
// 返回一个成功状态promise MyPromise.resolve = function (value) { return new MyPromise((resolve, reject) => { resolve(value); }) } // 返回一个失败状态promise MyPromise.reject = function (reason) { return new MyPromise((resolve, reject) => { reject(reason); }) } // 接受一个数组(数组中放置n个promise对象),只有所有promise对象都成成功状态,方法返回值的promise才是成功 // 只要有一个失败,方法返回值的promise就失败 MyPromise.all = function (promises) { // promises的长度 const promiseLength = promises.length; // 定义标识变量: promise对象成功的数量 let resolvedCount = 0; // 成功的结果值 const resolvedValues = []; return new MyPromise((resolve, reject) => { for (let i = 0; i < promiseLength; i++) { const promise = promises[i]; // 看promise的状态 promise.then((value) => { resolvedCount++; // 不能用push,输出顺序会乱 // 使用下标,才能保证顺序ok resolvedValues[i] = value; if (resolvedCount === promiseLength) { // 说明都成功了 resolve(resolvedValues); } }, reject) } }) }
const promise = new MyPromise((resolve, reject) => { console.log('executor函数执行了~'); setTimeout(() => { // resolve(111); reject(222); }, 2000) })
promise .then(() => { console.log(111); // 当then方法没有传入第二个回调。 // 那么一旦接受的promise对象的状态是失败状态,返回值也是失败状态 }) .catch((reason) => { console.log(222, reason); // return Promise.reject(); // throw new Error(111) return 333; }) .then((value) => { console.log(333, value); }) .catch(() => { console.log(444); })
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。