# 手写代码
# Promise
一个异步的解决方案,状态一旦确定就不能更改
三个状态:pending,fulfilled,rejected
# 从用法入手 , 一个最简单的例子:
let p = new Promise((resolve, reject) => {
resolve(1);
});
p.then((value) => {
console.log(1);
});
从上可得出,Promise是一个构造函数,传入一个函数作为参数,之后会同步的去执行这个函数,同时传入两个函数参数resolve和reject,这里我们使用ES6中Class来处理:
class Promise {
// 唯一状态
status = "pending";
// 成功后存储的值
resolveData = "";
// 失败后的错误数据
rejectData = "";
constructor(func) {
this.resolve = function (value) {
this.status = "fulfilled";
this.resolveData = value;
};
this.reject = function (error) {
this.status = "rejected";
this.rejectData = error;
};
func(this.resolve, this.reject);
}
}
我们定义好构造函数后,获取到了成功后的数据,需要添加then方法:
class Promise {
// ...
then(resolveThen, rejectThen) {
// 区分不同的状态
if (this.status === "fulfilled") {
resolveThen(this.resolveData);
}
if (this.status === "rejected") {
rejectThen(this.rejectData);
}
}
}
# 传递数据
由于promise对象可以不停的去传递返回值,所以需要处理返回的数据,实现链式调用
let p = new Promise((resolve, reject) => {
resolve(1);
});
p.then((value) => {
return value;
}).then((value) => {
console.log(value);
});
class Promise {
// ...
then(resolveThen, rejectThen) {
return new Promise((resolve, reject) => {
let result;
// 区分不同的状态
if (this.status === "fulfilled") {
result = resolveThen(this.resolveData);
resolve(result);
}
if (this.status === "rejected") {
result = rejectThen(this.rejectData);
reject(result);
}
});
}
}
# 异步
最常见的异步操作,我们需要在then中单独处理逻辑
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 5);
});
p.then((value) => {
return value;
}).then((value) => {
console.log(value);
});
class Promise {
// ...
// 处理异步的情况
resolveCbs = [];
rejectCbs = [];
constructor(func) {
this.resolve = function (value) {
this.status = "fulfilled";
this.resolveData = value;
this.resolveCbs.forEach((cb) => cb());
};
this.reject = function (error) {
this.status = "rejected";
this.rejectData = error;
this.rejectCbs.forEach((cb) => cb());
};
func(this.resolve, this.reject);
}
then(resolveThen, rejectThen) {
return new Promise((resolve, reject) => {
let result;
// 区分不同的状态
if (this.status === "fulfilled") {
result = resolveThen(this.resolveData);
resolve(result);
}
if (this.status === "rejected") {
result = rejectThen(this.rejectData);
reject(result);
}
// 异步
if (this.status === "pending") {
resolveThen &&
this.resolveCbs.push(() => {
result = resolveThen(this.resolveData);
if (isPromise(result)) {
// 外部如果有异步,可以通过宏任务队列排队执行
setTimeout(() => {
// 为了能够异步获取到result的值
resolve(result.resolveValue);
}, 5);
} else {
resolve(result);
}
});
rejectThen &&
this.rejectCbs.push(() => {
result = rejectThen(this.rejectData);
if (isPromise(result)) {
// 外部如果有异步,可以通过宏任务队列排队执行
setTimeout(() => {
reject(result.rejectValue);
}, 5);
} else {
reject(result);
}
});
}
});
}
}