// 三种状态
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
// promise 接收一个函数参数,该函数会立即执行
function MyPromise(fn) {

let _this = this;
_this.currentState = PENDING;
_this.value = undefined;
// 用于保存 then 中的回调,只有当 promise
// 状态为 pending 时才会缓存,并且每个实例至多缓存一个
_this.resolvedCallbacks = [];
_this.rejectedCallbacks = [];

_this.resolve = function (value) {
// console.log('aaaaa')
if (_this.currentState === PENDING) {
// console.log(_this.resolvedCallbacks)

_this.currentState = RESOLVED;
_this.value = value;

_this.resolvedCallbacks.forEach(cb => cb());
}
};

_this.reject = function (reason) {

if (_this.currentState === PENDING) {
_this.currentState = REJECTED;
_this.value = reason;
_this.rejectedCallbacks.forEach(cb => cb());
}
}

try {
fn(_this.resolve, _this.reject);
} catch (e) {
_this.reject(e);
}
}

MyPromise.prototype.then = function (onResolved, onRejected) {
var self = this;
var promise2;
if (self.currentState === RESOLVED) {
return (promise2 = new MyPromise(function (resolve, reject) {
var x = onResolved(self.value);
resolutionProcedure(promise2, x, resolve, reject)
}));
}

if (self.currentState === REJECTED) {
return (promise2 = new MyPromise(function (resolve, reject) {
var x = onRejected(self.value);
resolutionProcedure(promise2, x, resolve, reject)
}));
}

if (self.currentState === PENDING) {
return (promise2 = new MyPromise(function (resolve, reject) {
self.resolvedCallbacks.push(function () {
var x = onResolved(self.value);
resolutionProcedure(promise2, x, resolve, reject)
});

self.rejectedCallbacks.push(function () {
var x = onRejected(self.value);
resolutionProcedure(promise2, x, resolve, reject);
});
}));
}
};


function resolutionProcedure(promise2, x, resolve, reject) {

if(promise2 === x){
throw new Error('TypeError');
}
if (x instanceof MyPromise) {
console.log(x instanceof MyPromise)
if (x.currentState === PENDING) {
x.then(function (value) {
// 如果 x 是pending状态, promise 必须要在pending状态, 直到x的状态变更


resolutionProcedure(promise2, value, resolve, reject);
}, reject);
} else {
x.then(resolve, reject);
}
} else {
console.log(x instanceof MyPromise)
resolve(x);
}
return
}




// let p = new MyPromise(function(resolve, reject){
// //做一些异步操作
// setTimeout(function(){
// console.log('执行完成Promise');
// resolve('要返回的数据可以任何数据例如接口返回数据');
// }, 2000);
// });
// p.then(res => {
// console.log(res)
// return new MyPromise(function(resolve, reject){
// //做一些异步操作
// setTimeout(function(){
// console.log('异步任务2执行完成');
// resolve('随便什么数据2');
// }, 2000);
// });
// }).then(res => {
// console.log('555', res)
// })

// new MyPromise((resolve, reject) => {
// // resolve(); // 假如是同步执行的话。执行的时候resolvedCallbacks为空数组 在执行then currentState其实转化为其实经转化为resolved
// //
// setTimeout(function(){
// console.log('执行完成Promise');
// resolve('要返回的数据可以任何数据例如接口返回数据');
// }, 2000);
// console.log(1111);
// })
// .then(() => {
// console.log(2222);
// })




new MyPromise((resolve, reject) => {
console.log("外部promise");
resolve();
})
.then(() => {
console.log("外部第一个then");
return new MyPromise((resolve, reject) => {
console.log("内部promise");
resolve();
})
.then(() => {
console.log("内部第一个then");
})
.then(() => {
console.log("内部第二个then");
});
})
.then(() => {
console.log("外部第二个then");
});

不带状态的简易版 

class MyPromise {
constructor(fn) {
// 存储 reslove 回调函数列表
this.callbacks = []
const resolve = (value) => {
this.data = value // 返回值给后面的 .then
while (this.callbacks.length) {
let cb = this.callbacks.shift()
cb(value)
}
}
fn(resolve)
}
then(onResolvedCallback) {
return new MyPromise((resolve) => {
this.callbacks.push(() => {
const res = onResolvedCallback(this.data)
console.log(res instanceof MyPromise)
if (res instanceof MyPromise) {
res.then(resolve)
} else {
resolve(res)
}
})
})
}
}
// 这是测试案例
new MyPromise((resolve) => {
setTimeout(() => {
resolve(1)
}, 1000)
}).then((res) => {
console.log(res)
return new MyPromise((resolve) => {
setTimeout(() => {
resolve(2)
}, 1000)
})
}).then(res => { console.log(res) })

 resolutionProcedure为什么都是resolve

promise实现_数据

2021-11-13更新 改成 

// 1, 3种状态
// 2, 接收函数 先存在
// pending resolved rejected

class MyPromise {
constructor(fn) {
this.currentState = 'pending';
this.value = undefined;
this.resolvedCallbacks = [];
this.rejectedCallbacks = [];
this.resovle = (value) => {
if (this.currentState === 'pending') {
this.currentState = 'resolved';
this.value = value;
this.resolvedCallbacks.forEach(cb => {
cb();
})
}
}
this.reject = (value) => {
if (this.currentState === 'pending') {
this.currentState = 'rejected';
this.value = value;
this.rejectedCallbacks.forEach(cb => {
cb();
})
}
}
try {
fn(this.resovle, this.reject)
} catch (err) {
reject()
}
}
then(onResolved, onRejected) {
let promise2;
if (this.currentState === 'pending') {
return promise2 = (new Promise((resovle, reject) => {
this.resolvedCallbacks.push(() => { // 等待
let x = onResolved(this.value);
resolutionProcedure(promise2, x, resovle, reject)
})
this.rejectedCallbacks.push(() => { // 等待
let x = onRejected(this.value);
resolutionProcedure(promise2, x, resovle, reject)
})
}))
}
if (this.currentState === 'resolved') {
return (promise2 = new Promise((resovle, reject) => {
let x = onResolved(this.value);
resolutionProcedure(promise2, x, resovle, reject)
}))
}

if (this.currentState === 'rejected') {
return (promise2 = new Promise((resovle, reject) => {
let x = onRejected();
resolutionProcedure(promise2, x, resovle, reject)
}))
}
return this
}
}

function resolutionProcedure(promise2, x, resolve, reject) {
if (promise2 === x) {
throw new Error('TypeError')
}
if (x instanceof MyPromise) {
x.then(resolve, reject)

} else {
resolve(x);
}
return
}


new MyPromise((resolve, reject) => {
console.log("外部promise");
resolve(1);
})
.then((res) => {
console.log("外部第一个then");
console.log(res)
return new MyPromise((resolve, reject) => {
console.log(res)
console.log("内部promise");
setTimeout(() => {
resolve(res + 1);
}, 1000)
})
.then((res) => {
console.log(res)
console.log("内部第一个then");
return new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(res + 1);
}, 1000)
})
})
.then((res) => {
console.log(res)
console.log("内部第二个then");
return res + 1
});
})
.then((res) => {
console.log(res)
console.log("外部第二个then");
});