/**
*
* 问题1:怎么调用第二个then的onFullfilled函数呢
* 这也就是为啥我们要把第一个第一个promise中then的执行代码放到promise2中的原因
* 根据使用Promise我们知道:
* promise2是立即执行的,不影响执行顺序
* 第一个promise的onfullfilled函数的执行结果会传递个第二个then中,那么我们就把第一个then中
*
*
*
* 问题2:resolvePromise是用来具体做什么的?
* 其实就是用来处理第一个promise返回的值X的
*/
function Promise(executor) {
let self = this;
self.status = "pending";
self.value = undefined;
/*
这里为啥是个数组呢?什么时候会出现多个数组元素
这里用了发布订阅模式:数组用来保存成功和失败的回调函数
因为如果是异步的话,状态还未改变
*/
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value) {
if (value instanceof Promise) {
/**
* 为啥返回的是value.then()
*
*/
return value.then(resolve, reject)
}
setTimeout(function () {
/**
* 为啥异步执行所有的回调函数:
* */
if (self.status == 'pending') {
self.value = value;
// 改变状态为成功
self.status = 'resolved';
// 让所有的成功函数执行
self.onResolvedCallbacks.forEach(item => item(value));
}
});
}
function reject(value) {
setTimeout(function () {
if (self.status == 'pending') {
self.value = value;
// 改变状态为失败
self.status = 'rejected';
// 让所有的失败函数执行
self.onRejectedCallbacks.forEach(item => item(value));
}
});
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
// promise2 的成功或者失败取决于X
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('循环引用'));
}
let then, called;
if (x != null && ((typeof x == 'object' || typeof x == 'function'))) {
try {
// 取then可能会发生异常,不可枚举,不可以枚举的话直接reject(e);
// 缓存了then
then = x.then;
if (typeof then == 'function') {
// 这里用缓存的then,不要每次取x对象上找then,执行效率问题
then.call(x, function (y) {
if (called)return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, function (r) {
if (called)return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (e) {
if (called)return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
let self = this;
/**
* 这里为啥要做是不是函数的判断?
*/
onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : function (value) {
return value
};
onRejected = typeof onRejected == 'function' ? onRejected : function (value) {
throw value
};
let promise2;
if (self.status == 'resolved') {
/**
* 第一个promise不管成功还是失败,只要报错了就走第二个失败,只要不报错,那就走resolve,有resolve中去做具体判断
*/
promise2 = new Promise(function (resolve, reject) {
/**
* 这里为啥是异步的
* Q2:这也就是为啥我们要把第一个第一个promise中then的执行代码放到promise2中的原因
*
*/
setTimeout(function () {
/**
* 这里为啥是异步的!!!!!!!!!!!
* 原因就是在resolvePromise(promise2, x, resolve, reject)中使用了promise2,还没有声明promise2呢
* 类似于这个测试用例
function Test() {
setTimeout(() => {
console.log(a)
})
}
let a = new Test()
// 居然报错了: a is not defined 因为先new对象再声明变量,这个变量没有声明呢,如果变成异步的就好了
*/
try {
/**
* 为啥要把这段函数放在promise2里面执行呢?为啥要获取到x并且传给resolvePromise
* 因为resolvePromise是用来判断x的,根据x来决定promise2的成功或者失败
* 注意这里所有的都得捕获异常,并且捕获到的异常都要交给下一个then的onReject处理
*/
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (self.status == 'rejected') {
promise2 = new Promise(function (resolve, reject) {
setTimeout(function () {
try {
// 注意这里所有的都得捕获异常,并且捕获到的异常都要交给下一个then的onReject处理
let x = onRejected(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (self.status == 'pending') {
promise2 = new Promise(function (resolve, reject) {
self.onResolvedCallbacks.push(function (value) {
try {
// 注意这里所有的都得捕获异常,并且捕获到的异常都要交给下一个then的onReject处理
let x = onFulfilled(value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
self.onRejectedCallbacks.push(function (value) {
try {
// 注意这里所有的都得捕获异常,并且捕获到的异常都要交给下一个then的onReject处理
let x = onRejected(value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
return promise2;
}
Promise.prototype.catch = function (onRejected) {
return this.then(null, onRejected);
}
Promise.all = function (promises) {
return new Promise(function (resolve, reject) {
let result = [];
let count = 0;
for (let i = 0; i < promises.length; i++) {
promises[i].then(function (data) {
result[i] = data;
if (++count == promises.length) {
resolve(result);
}
}, function (err) {
reject(err);
});
}
});
}
Promise.deferred = Promise.defer = function () {
var defer = {};
defer.promise = new Promise(function (resolve, reject) {
defer.resolve = resolve;
defer.reject = reject;
})
return defer;
}
try {
module.exports = Promise
} catch (e) {
}