promise有一个then方法
- 1、构造函数
- 2、then方法
js
promise A+规范,有then方法就可以;所以难点是then方法
new Promise((resolve, reject) => {})
观察Promise的用法,构造函数会传入一个函数,执行器executor
resolve和reject两个函数用来改变状态,pending -》 fullfiled 或 pending-〉rejected
1 构造函数
kotlin
// 用常量定义字符串,利于维护
const PENDING = 'pending';
const FULLFIED = 'fullfied';
const REJECTED = 'rejected';
class MyPromise {
#status = PENDING; // 变量前加#,表示私有属性
#result = undefined;
#handlers = [];
constructor(executor) {
const resolve = (data) => {
this.#changeState(FULLFIED, data);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
// try catch 只能捕获同步错误
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
#changeState(status, data) {
if (this.#status !== PENDING) {
return;
}
this.#status = status;
this.#result = data;
console.log(this.#status, this.#result);
#run();
}
}
2 接下来考虑then

graph TD
then --> handler
then --> #run
#changeState --> #run
#run --> handler
arduino
// 传入的回调什么时候运行:将回调收集起来,用户可能会调用多次then,所以使用数组收集
// then返回的promise
// 挂起的状态,有异步代码情况,所以需要状态改变时执行回调函数
// 将回调函数都收集起来
// 传入的回调不是函数,穿透
// 目前状态是成功,传入的回调不是函数
// 目前状态是失败,传入的回调不是函数
// 运行回调函数,返回回调函数运行结果【&执行回调】
js
#runOne(callback, resolve, reject) {
if (typeof callback !== 'function') {
const settled = this.#status === FULLFIED ? resolve : reject;
settled(this.#result);
return;
}
try {
const data = callback(this.#result);
resolve(data);【&执行回调】
} catch (err) {
reject(err);
}
}
// 在changeState状态改变函数中也要调用run方法
#run() {
if (this.#status === PENDING) return;
while (this.#handlers.length) {
const { onFullfilled, onRejected, resolve, reject } =
this.#handlers.shift();
if (this.#status === FULLFIED) {
this.#runOne(onFullfilled, resolve, reject);
} else {
this.#runOne(onRejected, resolve, reject);
}
// 提取函数runOne
// if (this.#status === FULLFIED) {
// if (typeof onFullfilled === 'function') {
// try {
// const data = onFullfilled(this.#result);
// resolve(data);
// } catch (err) {
// reject(err);
// }
// } else {
// resolve(this.#result);
// }
// } else {
// if (typeof onRejected === 'function') {
// try {
// const data = onRejected(this.#result);
// resolve(data);
// } catch (err) {
// reject(err);
// }
// onRejected(this.#result);
// } else {
// // 目前状态时成功,传入的回调不是函数
// // 目前状态时失败,传入的回调不是函数
// // 穿透,resolve或者reject
// // 穿透
// reject(this.#result);
// }
// }
}
}
// 传入的回调什么时候运行:将回调收集起来,用户可能会调用多次then,所以使用数组收集
// then返回的promise
then(onFullfilled, onRejected) {
return new Promise((resolve, reject) => {
// 挂起的状态,有异步代码情况,所以需要状态改变时执行回调函数
// 将回调函数都收集起来
this.#handlers.push({
onFullfilled,
onRejected,
resolve,
reject,
});
this.#run();
});
}
js
const p = new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(234);
}, 1000);
// throw 123;
});
console.log(p);
p.then(
(res) => {
console.log('成功1', res);
},
(err) => {
console.log('失败1', err);
}
);
p.then(
// (res) => {
// console.log('成功2', res);
// },
null,
(err) => {
console.log('失败2', err);
}
);
p.then(
(res) => {
console.log('成功3', res);
},
(err) => {
console.log('失败3', err);
return 222;
}
).then((res) => {
console.log(res);
});
// 原生promise也无法捕获异步错误
// const p1 = new Promise((resolve, reject) => {
// setTimeout(() => {
// throw 123;
// }, 0);
// });