diff --git a/index.js b/index.js index 59d6c84..ee56d81 100644 --- a/index.js +++ b/index.js @@ -1,22 +1,47 @@ function myPromise(constructor) { let self = this; - self.status = "pending" //定义状态改变前的初始状态 + self.status = "pending" //定义状态改变前的初始状态 pending resolved rejected self.value = undefined;//定义状态为resolved的时候的状态 self.reason = undefined;//定义状态为rejected的时候的状态 - function resolve(value) { - - // TODO resolve如何改变状态及返回结果 + self.resolveFnArr = []; + self.rejectFnArr = []; + + function changeStatus(status, value) { + if (self.status !== 'pending') { + return; + } + self.status = status; + self.value = value; + let fnArr = self.status === 'resolved' ? self.resolveFnArr : self.rejectFnArr; + if (fnArr.length > 0) { + fnArr.forEach(item => { + item(value); + }); + } + } + function resolve(value) { + if (self.resolveFnArr.length > 0) { + changeStatus('resolved', value); + } + let timer = setTimeout(() => { + changeStatus('resolved', value); + clearTimeout(timer); + }, 0) } function reject(reason) { - - // TODO reject如何改变状态及返回结果 - + if (self.rejectFnArr.length > 0) { + changeStatus('rejected', reason); + } + let timer = setTimeout(() => { + changeStatus('rejected', reason); + clearTimeout(timer); + }, 0); } //捕获构造异常 @@ -34,8 +59,49 @@ function myPromise(constructor) { } myPromise.prototype.then = function (onFullfilled, onRejected) { + if (typeof onFullfilled !== 'function') { + onFullfilled = (res) => { + return res; + } + } + if (typeof onRejected !== 'function') { + onRejected = (reason) => { + return new myPromise((_, reject) => { + reject(reason); + }) + } + } + return new myPromise((resolve, reject) => { + this.resolveFnArr.push((res) => { + try { + let excuteRes = onFullfilled(res); + if (excuteRes instanceof myPromise) { + excuteRes.then(resolve, reject); + } else { + resolve(excuteRes); + } + } catch (error) { + reject(error); + } + }); + this.rejectFnArr.push((reason) => { + try { + let excuteRes = onRejected(reason); + if (excuteRes instanceof myPromise) { + excuteRes.then(resolve, reject); + } else { + resolve(excuteRes); + } + } catch (error) { + reject(error); + } + }); + }) +} - //TODO then如何实现 - +myPromise.prototype.catch = function (rejectFn) { + return this.then(null, rejectFn); } -module.exports = myPromise + + +module.exports = myPromise; diff --git a/index.test.js b/index.test.js index cbb1027..8e52fc8 100644 --- a/index.test.js +++ b/index.test.js @@ -1,9 +1,25 @@ const myPromise = require('./index'); -var p = new myPromise(function (resolve, reject) { resolve('isOk') }); -test('测试primose的then是否成功', () => { - expect.assertions(1); - return p.then(data => { - expect(data).toBe('isOk'); +var ok = new myPromise(function (resolve, reject) { resolve('isOk') }); +var notOk = new myPromise(function (resolve, reject) { reject('isNotOk') }); +describe('promise', function () { + test('测试primose的then是否成功', () => { + expect.assertions(1); + return ok.then(data => { + return data; + }).then(data => { + expect(data).toBe('isOk'); + }); }); -}); \ No newline at end of file + test('测试primose的catch是否成功', () => { + expect.assertions(1); + return notOk + .then((res) => { + console.log('nothing'); + }) + .catch(data => { + expect(data).toBe('isNotOk'); + }); + }); +}); +