const PENDING = 'PENDING';
const RESOLVE = 'RESOLVE';
const REJECTED = 'REJECTED';
resolvePromise = (promise2,resolve,reject) => {
if(promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
}
if(typeof x === 'object' && x !== null || typeof x === 'function') {
let called; // 内部测试
try {
let then = x.then;
if(typeof then === 'function') {
then.call(x, y => { // y 可能还是 promise 递归
if(called) {
return;
}
called = true;
resolvePromise(promise2, y, resolve, reject); // 采用 promise 成功结果的值向下传递
},r => {
if(called) {
return;
}
called = true;
reject(r);// 采用失败结果向下传递
})
} else {
resolve(x); // 说明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 = RESOLVE;
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 : data => data;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
let promise2 = new Promise((resolve, reject) => {
if (this.state === RESOLVE) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
// x 可能是普通纸 也可能是 promise
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e)
}
},0)
}
if (this.state === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
// x 可能是普通纸 也可能是 promise
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e)
}
},0)
}
if (this.state === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
// x 可能是普通纸 也可能是 promise
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e)
}
},0)
})
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
// x 可能是普通纸 也可能是 promise
resolvePromise(promise2, x, resolve, reject);
} catch(e) {
reject(e)
}
},0)
})
}
})
}
}
const isPromise = (value) => {
if(typeof value === 'object' && value !== null || typeof value === 'function') {
if (typeof value.then === 'function') {
return true;
}else {
return false;
}
}
}
Promise.all = function(values) {
return new Promise((resolve, reject) => {
let arr = [];
let index = 0;
function processData(key, value) {
arr[key] = value;
if(index++ == values.length) {
resolve(arr);
}
}
for(let i = 0; i < values.length; i++) {
let current = values[i];
if (isPromise(current)) {
current.then((data) => {
processData(i, data);
}, reject);
}else {processData(i, current);
}
}
})
}
Promise.prototype.finally = function(cb) {
return package.then(data => {
return Promise.resolve(cb()).then(() => data);
}, err => {
Promise.resolve(cb()).then(() => {
throw err;
});
})
}
module.exports = Promise;
网友评论