function Promise2(cb) {
this.state = 'pedding'
this.value
this.reason
this.fulfilledFns = []
this.rejectedFns = []
const resolve = (val) => {
if (this.state === 'pedding') {
this.value = val
this.state = 'fulfilled'
setTimeout(() => {
this.fulfilledFns.forEach(fn => {
fn(this.value)
})
}
}
const reject = (val) => {
if (this.state === 'pedding') {
this.state = 'rejected'
this.reason = val
setTimeout(() => {
this.rejectedFns.forEach(fn => {
fn(this.reason)
})
})
}
}
try {
cb(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise2.prototype.then = function (resolveFn, rejectFn) {
resolveFn = typeof resolveFn === 'function' ? resolveFn : () => { }
rejectFn = typeof rejectFn === 'function' ? rejectFn : () => { }
let promise2
switch (this.state) {
case 'pedding':
promise2 = new Promise2((resolve, reject) => {
这里应该使用resolve的,,因为下一层的then 从resolveFn 开始
this.fulfilledFns.push(() => {resolvePromise(promise2, resolveFn(this.value), resolve, reject) })
this.rejectedFns.push(() => { resolvePromise(promise2, rejectFn(this.reason), resolve, reject) })
})
break;
case 'fulfilled':
promise2 = new Promise2((resolve, reject) => {
try {
resolvePromise(promise2, rejectedFns(this.value), resolve, reject)
} catch (e) {
reject(e);
}
})
break;
case 'rejected':
promise2 = new Promise2((resolve, reject) => {
try {
这里应该使用resolve的,因为下一层的then 从resolveFn 开始
resolvePromise(promise2, rejectedFns(this.reason), resolve, reject)
} catch (e) {
reject(e);
}
})
break;
}
return promise2
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'))
}
let called
if (x !== null && (typeof x === 'object' || 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)
}, err => {
if (called) {
return
}
called = true
reject(err)
})
} else {
resolve(x)
}
} catch (err) {
if (called) {
return
}
called = true
reject(err);
}
} else {
resolve(x)
}
}