function callAsync(fn, arg, callback, onError) {
process.nextTick(function () {
try {
callback ? callback(fn(arg)) : fn(arg);
} catch (e) {
onError(e);
}
});
}
function CustomPromise(handle) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledFunc = [];
this.onRejectedFunc = [];
try {
handle(resolve, reject);
} catch (error) {
reject(error);
}
function resolve(value) {
if (this.status == "pending") {
this.status = "resolved";
this.value = value;
this.onFulfilledFunc.forEach(fn => fn(value));
}
}
function reject(reason) {
if (this.status == "pending") {
this.status = "rejected";
this.reason = reason;
this.onFulfilledFunc.forEach(fn => fn(reason));
}
}
}
CustomPromise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
var self = this;
var res = null;
var returnPromise = new Promise(function (resolve, reject) {
if (this.status == "resolved") {
setTimeout(() => {
try {
res = onFulfilled(self.value);
resolvePromise(returnPromise, res, resolve, reject);
} catch (err) {
reject(err);
}
}, 0)
}
if (this.status == "rejected") {
setTimeout(() => {
try {
res = onrejected(self.value);
resolvePromise(returnPromise, res, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
}
if (this.status == "pedding") {
self.onFulfilledFunc.push(function () {
setTimeout(() => {
try {
res = onFulfilled(self.value);
resolvePromise(returnPromise, res, resolve, reject);
} catch (err) {
reject(err);
}
}, 0)
});
self.onRejectedFunc.push(function () {
setTimeout(() => {
try {
res = onrejected(self.value);
resolvePromise(returnPromise, res, resolve, reject);
} catch (e) {
reject(e);
}
}, 0)
})
}
});
return returnPromise;
}
CustomPromise.prototype.resolvePromise = function (promise, res, resolve, reject) {
if (promise === res) {
return reject(new TypeError('循环引用'))
}
let called;
if (res !== null && (typeof res === 'function' || typeof res === 'object')) {
try {
let then = res.then;
if (typeof then === 'function') {
then.call(res, (res2) => {
if (called) return;
called = true;
resolvePromise(promise, res2, resolve, reject);
})
} else {
if (called) return;
called = true;
resolve(then)
}
} catch (e) {
if (called) return;
called = true;
reject(e)
}
} else {
resolve(res)
}
}
CustomPromise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
}
CustomPromise.prototype.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject);
}
})
}
CustomPromise.prototype.all = function (promises) {
let arr = [];
let i = 0;
function processData(index, data) {
arr[index] = data;
i++;
if (i == promises.length) {
resolve(arr);
}
};
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(data => {
processData[i, data];
}, reject);
};
});
}