/*
1、Promise就是一个类,在执行这个类的时候,需要传递一个执行器进去,执行器就会立即执行
2、Promise中有三种状态,分别是成功fulfilled、失败rejected、等待pending
pending->fulfilled
pending->rejected
一旦状态确定就不会改变
3、resolve和reject函数是用来更改状态的
resolve:fulfilled
reject:rejected
4、then方法内部做的事情就判断状态
如果状态是成功,调用成功的回调函数
如果状态是失败,调用失败的回调函数
then方法是被定义在原型对象中的
5、then成功回调有一个参数,表示成功之后的值,then失败回调有一个参数,表示失败后的原因
6、同一个promise对象下面的then方法是可以被调用多次的
7、then方法可以被链式调用,后面的then方法的回调函数拿到值的是上一个then方法的回调函数的返回值
8、all、finally方法编写
*/
const PENDING = 'pending'
const FULFILLED = 'fulfiled'
const REJECTED = 'rejected'
class MyPromise{
constructor(executor){
//捕获执行器错误
try{
executor(this.resolve,this.reject)
}catch(e){
this.reject(e)
}
}
//Promise状态
status = PENDING
//成功之后的值
value = undefined
//失败后的原因
reason = undefined
//成功回调
successCallback = [];
//失败回调
failCallback = [];
resolve = value => {
//如果状态不是等待,阻止程序向下执行
if(this.status !== PENDING) return
//将状态更改为成功
this.status = FULFILLED
//保存成功之后的值
this.value = value
// 判断成功回调是否存在 如果存在 调用
// this.successCallback && this.successCallback(this.value);
while(this.successCallback.length)
this.successCallback.shift()(this.value)
}
reject = reason => {
//如果状态不是等待,阻止程序向下执行
if(this.status !== PENDING) return
//将状态更改为失败
this.status = REJECTED
//保存失败后的原因
this.reason = reason
// 判断失败回调是否存在 如果存在 调用
// this.failCallback&& this.failCallback(this.reason);
while(this.failCallback.length)
this.failCallback.shift()(this.reason)
}
then(successCallback,failCallback){
//参数可选
successCallback = successCallback ? successCallback : value => value
failCallback = failCallback ? failCallback: reason=> {throw reason}
let promise1 = new MyPromise((resolve,reject)=>{
//判断状态
if(this.status === FULFILLED){
//将同步代码转成异步代码
setTimeout(()=>{
try{
let x = successCallback(this.value)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promise1,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else if(this.status === REJECTED ){
//将同步代码转成异步代码
setTimeout(()=>{
try{
let x = failCallback(this.reason)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promise1,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
}else{
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(()=>{
setTimeout(()=>{
try{
let x = successCallback(this.value)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promise1,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
this.failCallback.push(()=>{
//将同步代码转成异步代码
setTimeout(()=>{
try{
let x = failCallback(this.reason)
// 判断 x 的值是普通值还是promise对象
// 如果是普通值 直接调用resolve
// 如果是promise对象 查看promsie对象返回的结果
// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
resolvePromise(promise1,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
}
})
return promise1
}
/*
finally方法特点:
无论当前Promise对象最终是成功还是失败,finally方法都会被执行;
在finally方法后面可以链式调用then方法来拿到当前Promise对象返回的结果
*/
finally(callback){
return this.then(value=>{
//成功的回调
return MyPromise.resolve(callback()).then(()=>value)
},reason=>{
//失败的回调
return MyPromise.resolve(callback()).then(()=>{throw reason})
})
}
//catch方法处理当前Promise对象最终状态为失败的情况
catch (failCallback) {
return this.then(undefined, failCallback)
}
static all(array){
let result = []
let index = 0
function addData (key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
return new MyPromise((resolve,reject)=>{
for(let i = 0;i < array.length;i++){
let current = array[i]
if(current instanceof MyPromise){
//Promise对象
current.then(value => addData(i, value), reason => reject(reason))
}else{
//普通值
addData(i, array[i]);
}
}
})
}
static resolve(value){
if(value instanceof MyPromise)
return value
return new MyPromise(resolve => resolve(value))
}
}
//链式调用
function resolvePromise (promise1, x, resolve, reject) {
if(promise1 === x){
reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (x instanceof MyPromise) {
// promise 对象
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise