有不对的,可以指出来,我这里只是想记一下笔记,方便我以后看。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
let st = setTimeout;
const FULL_FILLED = 'fullFilled'; // 成功
const REJECTED = 'rejected'; // 失败
const PENDING = 'pending';//这里用的setTimeout做异步操作,所以在执行异步之前的时间里,状态都是pending
let count = 0;
let Promise = function (fn) {//fn就是promise中的函数参数,这个参数有两个内部定义好的resolve和reject函数参数
this.id = count++;
this.status = PENDING;
this.successCallbacks = [];//用来保存then里边的成功回调函数
this.failedCallbacks = [];//用来保存then里边失败的回调函数
let resolve = (v)=> {//promise的resolve执行,后会执行then中的成功回调函数,这个v参数,会传过去
setTimeout(()=>{
// resolve(value);
this.value = v;
this.status = FULL_FILLED;//如果成功会从pending状态变成fullFilled
this.successCallbacks.forEach( fn => fn(this.value) )
})
}
let reject = (v) => {
setTimeout(()=>{
// reject(value);
this.value = v;
this.status = REJECTED;//失败的话从pending状态变成rejected状态
this.failedCallbacks.forEach( fn => fn(this.value) )
})
}
try {
fn(resolve,reject)
} catch (e) {
reject(e); // new Promise().then 执行失败
}
}
function excutePromise (promiseOrVal,resolve,reject) {//这是第一个参数,是判断then中的返回是一个【promise】还是【普通的基本类型值】
if (promiseOrVal instanceof Promise) {
// 还没有写 (then 从promise中取值)
promiseOrVal.then((v)=>{
excutePromise(v,resolve,reject);//这个就是一直递归判断then中返回的是不是promise还是基本值的函数
});
} else {
// value 基本数据类型
resolve(promiseOrVal); // then中如果返回的是【基本类型的值】执行resolve函数,就直接进行到下一个的.then的回调函数里面,否则的话就是promise,继续进行循环递归去判断返回的是promise还是基本类型值
}
}
// then 一定是要返回Promise供外部.then
Promise.prototype.then = function (onFullFilledFn,onRejectedFn) {
let chainPromise;//这个结果就是then的返回值,一定要是promise,供外部的.then
// 如果当前,3秒以内,状态是【Pending】
if (this.status === PENDING) {//如果是pending状态,就说明,也不知道要走成功还是失败,所以有两种可能
chainPromise = new Promise((resolve,reject)=>{
// 是pending状态,先把成功或者是失败的回调函数保存起来,等待状态改变后,直接调用,这个目的就是保存函数
this.successCallbacks.push(()=>{
try {
setTimeout(()=>{
// resovle后才会被发布,所执行
let value = onFullFilledFn(this.value);
// value有可能是Promise, 也有可能是一般的值
excutePromise(value,resolve,reject);//这个函数就是去判断返回的值是否是promise还是基本值,基本值的话,就会执行resolve,想定与放行开关,进入到下一个then中
})
}catch(e) {
reject(e);
}
});
this.failedCallbacks.push(()=>{
try {
setTimeout(()=>{
// reject后才会被发布,所执行
let value = onRejectedFn(this.value);
// value有可能是Promise, 也有可能是一般的值
excutePromise(value,resolve,reject);
})
}catch(e) {
reject(e);
}
})
});
}
if (this.status === FULL_FILLED) {//如果状态是成功,直接走成功回调
chainPromise = new Promise((resolve,reject) => {
try {
setTimeout(()=>{
let value = onFullFilledFn(this.value);
excutePromise(value,resolve,reject);
})
} catch (e) {
reject(e);
}
});
}
if (this.status === REJECTED) {//如果状态是失败
chainPromise = new Promise((resolve,reject) => {
try {
let value = onRejectedFn(this.value);
excutePromise(value,resolve,reject);
} catch (e) {
reject(e);
}
});
}
return chainPromise;
}
// 模拟3组异步
// 返回的是Promise实例
new Promise(function (resolve,reject) {
console.log('promise执行了');//1
st(()=>{
console.log('第1件事。。。');//2
resolve('abcd');
},3000);
})
.then( (data)=> {
return new Promise((resovle,reject)=>{
st(()=>{
console.log('第2件事');//3
resovle('xxx');//这个执行了,才会执行下一个then,它就是一个开关作用,这个参数会作为下一个then的实参,
},3000);
});
})
.then((d)=>{
console.log('结束了',d);//4,d的值:【d:'xxx'】
})
</script>
</body>
</html>
.then一定是一个promise,供外部(后续)的.then才能执行,
.then 是立刻执行的,没办法控制它停止,每个then里的回调函数,有可能是一个promise
或者一个普通的基本类型的值,如果是promise,只有resolve,才会执行下一个then里的
回调函数,否则直接往下执行;(有一个递归就是判断then里的回调函数是不是一个promise,如果是
就继续递归)