// var flag = 1;
// var a = new Promise(function (resolve, reject) {
// if (flag) {
// resolve(1);
// } else {
// reject(0);
// }
// });
// a.then(function (res) {
// console.log('ok-', res);
// }, function (err) {
// console.log('err-', err);
// });
// a.then(function (res) {
// console.log('ok2-', res);
// }).catch(function () {
// console.log('err2-', err);
// });
// 三种状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function myPromise (callback) {
var _this = this;
_this.val = null;
_this.reason = null;
_this.currentState = PENDING;
_this.onResolvecalls = [];
_this.onRejectcalls = [];
_this.resolve = function (res) {
if (_this.currentState === PENDING) {
_this.currentState = FULFILLED;
_this.val = res;
while (_this.onResolvecalls.length) {
var call = _this.onResolvecalls.shift();
call(res);
}
}
};
_this.reject = function (reason) {
if (_this.currentState === PENDING) {
_this.currentState = REJECTED;
_this.reason = reason;
while (_this.onRejectcalls.length) {
var call = _this.onRejectcalls.shift();
call(reason);
}
}
};
// 解决方法报错异常处理
try {
callback(_this.resolve, _this.reject);
} catch (error) {
_this.reject(error.reason);
}
}
myPromise.prototype.then = function (succ, fail) {
succ = typeof succ === 'function' ? succ : val => val;
fail = typeof fail === 'function' ? fail : (reason) => { throw reason; };
const promise2 = new myPromise((resolve, reject) => {
if (this.currentState === FULFILLED) {
// 等于succ的返回值
// 有返回值的话会传递给下一个then
// 没有返回值的话会是undefind
queueMicrotask(() => {
try {
const x = succ(this.val);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
return reject(err.reason);
}
});
} else if (this.currentState === REJECTED) {
// 等待fail的返回值
// 判断是否有返回值,没有为undefined
// 判断返回值是否为promise
// 有的话需要执行后再返回用来终结promise2
queueMicrotask(() => {
try {
const x = fail(this.reason);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
return reject(err);
}
});
} else {
succ && this.onResolvecalls.push(() => {
queueMicrotask(() => {
try {
const x = succ(this.val);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
return reject(err.reason);
}
});
});
fail && this.onRejectcalls.push(() => {
queueMicrotask(() => {
try {
const x = fail(this.reason);
resolvePromise(x, promise2, resolve, reject);
} catch (err) {
return reject(err);
}
});
});
}
});
return promise2;
};
myPromise.prototype.catch = function (fail) {
return this.then(null, fail);
};
// 静态方法的处理
myPromise.resolve = function (parameter) {
if (parameter instanceof myPromise) {
return parameter;
} else {
return new myPromise((resolve) => {
console.log('parameter');
console.log(parameter);
resolve(parameter);
});
}
};
myPromise.reject = function (reason) {
return new myPromise((resolve, reject) => {
reject(reason);
});
};
myPromise.all = function (list) {
return new myPromise((resolve, reject) => {
const result = [];
const len = list.length;
let cont = 0;
if (len === 0) {
return resolve(result);
}
list.forEach((promise, index) => {
myPromise.resolve(promise).then((val) => {
result[index] = val;
cont++;
console.log(cont);
if (cont === len) {
console.log(result);
resolve(result);
}
}, (reason) => {
reject(reason);
});
});
});
};
function resolvePromise (x, promise2, resolve, reject) {
/**
* 判断x是否是promise
* 是的话需要执行then,将thenPromise由PENDING转换成别的状态
* 因为x结束之后会执行then里面的方法进而更新thenPromise的状态
*
* 如果不是需要直接返回值
*/
// Uncaught ReferenceError: Cannot access 'promise2' before initialization
// 需要等待promise2完成初始化操作
// 调用resolvePromise的时候promise2内部代码还没有走完
// 相同不会抛出x造成死循环
// 相等需要抛出错误并且返回
if (x === promise2) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
}
// if (x instanceof myPromise) {
// x.then(resolve, reject);
// 判断x是否为promise
if (typeof x === 'object' || typeof x === 'function') {
if (x === null) {
return resolve(x);
}
let then;
// 取值then,没有则抛出错误
try {
then = x.then;
} catch (error) {
return reject(error);
}
if (typeof then === 'function') {
let called = false;
try {
then.call(x, y => {
// 如果 resolvePromise 和 rejectPromise 均被调用,
// 或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用
// 实现这条需要前面加一个变量 called
if (called) {
return;
}
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => {
// 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise
if (called) {
return;
}
called = true;
reject(r);
});
} catch (error) {
// 如果调用 then 方法抛出了异常 error:
// 如果 resolvePromise 或 rejectPromise 已经被调用,直接返回
if (called) {
return;
}
reject(error);
}
} else {
resolve(x);
}
} else {
resolve(x);
}
}
// var flag = 1;
// var a = new myPromise(function (resolve, reject) {
// resolve(1);
// // setTimeout(function () {
// // if (flag) {
// // resolve(1);
// // } else {
// // reject(0);
// // }
// // });
// });
// function other () {
// return new myPromise((resolve, reject) => {
// resolve('other');
// });
// }
// then内部会再抛出一个promise来解决链式调用问题
// a.then(function (res) {
// console.log('ok2-', res);
// }).catch(function () {
// console.log('err2-', err);
// });
/************** 异常捕获 **************/
// // promise相等造成的死循环问题
// // 会抛出错误
// const p1 = a.then(value => {
// console.log(1);
// console.log('resolve', value);
// return p1;
// });
// // 运行的时候会走reject
// p1.then(value => {
// console.log(2);
// console.log('resolve', value);
// }, reason => {
// console.log(3);
// console.log(reason.message);
// });
// callback出错异常捕获
// var p = new myPromise(function (resolve, reject) {
// throw new Error('执行器错误');
// });
// p.then((res) => {
// console.log('ok-', res);
// }, (err) => {
// console.log('err-', err.message);
// });
// then出错异常捕获
// const promise = new myPromise((resolve, reject) => {
// resolve('success');
// // throw new Error('执行器错误')
// });
// // 第一个then方法中的错误要在第二个then方法中捕获到
// promise.then(value => {
// console.log(1);
// console.log('resolve', value);
// throw new Error('then error');
// }, reason => {
// console.log(2);
// console.log(reason.message);
// }).then(value => {
// console.log(3);
// console.log(value);
// }, reason => {
// console.log(4);
// console.log(reason.message);
// });
// then中队列函数的处理
// 函数的异常处理
// function other () {
// return new myPromise((resolve, reject) => {
// resolve('other');
// });
// }
// const p = new myPromise((resolve, reject) => {
// setTimeout(() => {
// resolve('success');
// });
// });
// p.then((res) => {
// console.log('ok-', res);
// return other();
// }).then((res) => {
// console.log('ok2-', res);
// });
// then中的参数为可选
// const promise = new myPromise((resolve, reject) => {
// resolve(100);
// // reject(100);
// });
// promise.then().then().then().then(value => console.log(value));
// promise.then().then().then().catch(value => console.log(value));
// 静态方法调用
// myPromise.resolve().then(() => {
// console.log(0);
// return MyPromise.resolve(4);
// }).then((res) => {
// console.log(res);
// });
// 此时已经发现回调函数的执行结果返回的是一个 Promise (即:return Promise.resove(4)),然而在 V8 中没有立即去处理它,而是将其包裹起来送入微任务队列,做了异步执行处理。
// myPromise.resolve().then(() => {
// console.log(0);
// return myPromise.resolve(4);
// }).then((res) => {
// console.log(res);
// });
// myPromise.resolve().then(() => {
// console.log(1);
// }).then(() => {
// console.log(2);
// }).then(() => {
// console.log(3);
// }).then(() => {
// console.log(5);
// }).then(() => {
// console.log(6);
// });
// 大家先思考一下
// all方法
var a = new myPromise(function (resolve, reject) {
setTimeout(() => {
resolve(1);
}, 1000);
});
var b = new myPromise(function (resolve, reject) {
setTimeout(() => {
resolve(2);
}, 3000);
});
var c = new myPromise(function (resolve, reject) {
setTimeout(() => {
resolve(3);
}, 2000);
});
var list = [a, b, c];
myPromise.all(list).then(function (list) {
list.forEach(element => {
console.log(element);
});
});
console