1. 初始化结构搭建
2. 同步修改状态then方法结果返回
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
// 实例化对象
let p = new Promise((resolve, reject) => {
resolve("OK");
});
// 执行then方法
const res = p.then(
(value) => {
// console.log(value);
// return "hello Promise";
// return new Promise((resolve, reject) => {
// resolve("success");
// });
throw "fail";
},
(reason) => {
console.warn(reason);
}
);
console.log(res);
</script>
</body>
</html>
promise.js
// 声明构造函数
function Promise(executor) {
// 添加属性
this.PromiseState = "pending";
this.PromiseResult = null;
// 声明属性
this.callbacks = [];
// 保存实例对象的 this 值
const self = this;
// resolve 函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "fulfilled"; // solved
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
// 调用成功的回调函数
self.callbacks.forEach((item) => {
item.onResolved(data);
});
}
// reject 函数
function reject(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "rejected";
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
// 调用失败的回调函数
self.callbacks.forEach((item) => {
item.onRejected(data);
});
}
try {
// 同步调用 执行器函数
executor(resolve, reject);
} catch (error) {
// 修改 promise 对象状态为 失败
reject(error);
}
}
// 添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
return new Promise((resolve, reject) => {
// 调用回调函数 PromiseState
if (this.PromiseState === "fulfilled") {
// 获取回调函数的执行结果
// 根据回调函数的执行结果,改变promise对象的状态
try {
let result = onResolved(this.PromiseResult);
// 判断
if (result instanceof Promise) {
// 如果是 Promise 类型的对象
result.then(
(v) => {
resolve(v); // 设置成功的结果为return的结果
},
(r) => {
reject(r);
}
);
} else {
// 结果的对象状态为 成功
resolve(result); // 设置成功的结果为return的结果
}
} catch (error) {
reject(error);
}
}
if (this.PromiseState === "rejected") {
onRejected(this.PromiseResult);
}
// 判断 pending 状态
if (this.PromiseState === "pending") {
// 保存回调函数
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected,
});
}
});
};
3. 异步修改状态then方法结果返回
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
// 实例化对象
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve("OK");
reject("error");
}, 1000);
});
// 执行then方法
const res = p.then(
(value) => {
// return "OK";
throw "error";
},
(reason) => {
// 因为返回的是undefined,所以then方法返回的promise对象的状态变成了成功
// console.warn(reason);
throw "error";
}
);
console.log(res);
</script>
</body>
</html>
promise.js
// 声明构造函数
function Promise(executor) {
// 添加属性
this.PromiseState = "pending";
this.PromiseResult = null;
// 声明属性
this.callbacks = [];
// 保存实例对象的 this 值
const self = this;
// resolve 函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "fulfilled"; // solved
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
// 调用成功的回调函数
self.callbacks.forEach((item) => {
item.onResolved(data);
});
}
// reject 函数
function reject(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "rejected";
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
// 调用失败的回调函数
self.callbacks.forEach((item) => {
item.onRejected(data);
});
}
try {
// 同步调用 执行器函数
executor(resolve, reject);
} catch (error) {
// 修改 promise 对象状态为 失败
reject(error);
}
}
// 添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
const self = this;
return new Promise((resolve, reject) => {
// 调用回调函数 PromiseState
if (this.PromiseState === "fulfilled") {
// 获取回调函数的执行结果
// 根据回调函数的执行结果,改变promise对象的状态
try {
let result = onResolved(this.PromiseResult);
// 判断
if (result instanceof Promise) {
// 如果是 Promise 类型的对象
result.then(
(v) => {
resolve(v); // 设置成功的结果为return的结果
},
(r) => {
reject(r);
}
);
} else {
// 结果的对象状态为 成功
resolve(result); // 设置成功的结果为return的结果
}
} catch (error) {
reject(error);
}
}
if (this.PromiseState === "rejected") {
onRejected(this.PromiseResult);
}
// 判断 pending 状态
if (this.PromiseState === "pending") {
// 保存回调函数
this.callbacks.push({
// 根据回调函数的执行结果决定状态
onResolved: function () {
try {
// 执行成功的回调函数
let result = onResolved(self.PromiseResult);
// 判断
// 根据result的结果判断state
if (result instanceof Promise) {
result.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
},
onRejected: function () {
try {
// 执行失败的回调函数
let result = onRejected(self.PromiseResult);
// 判断
// 根据result的结果判断state
if (result instanceof Promise) {
result.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
},
});
}
});
};
4. then方法的完善与优化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
// 实例化对象
let p = new Promise((resolve, reject) => {
resolve("OK");
// reject("error");
});
// 执行then方法
const res = p.then(
(value) => {
console.log(value);
},
(reason) => {
// 因为返回的是undefined,所以then方法返回的promise对象的状态变成了成功
console.warn(reason);
}
);
console.log(res);
</script>
</body>
</html>
promise.js
// 声明构造函数
function Promise(executor) {
// 添加属性
this.PromiseState = "pending";
this.PromiseResult = null;
// 声明属性
this.callbacks = [];
// 保存实例对象的 this 值
const self = this;
// resolve 函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "fulfilled"; // solved
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
// 调用成功的回调函数
self.callbacks.forEach((item) => {
item.onResolved(data);
});
}
// reject 函数
function reject(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "rejected";
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
// 调用失败的回调函数
self.callbacks.forEach((item) => {
item.onRejected(data);
});
}
try {
// 同步调用 执行器函数
executor(resolve, reject);
} catch (error) {
// 修改 promise 对象状态为 失败
reject(error);
}
}
// 添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
const self = this;
return new Promise((resolve, reject) => {
// 封装函数
function callback(type) {
try {
let result = type(self.PromiseResult);
if (result instanceof Promise) {
result.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
// 调用回调函数 PromiseState
if (this.PromiseState === "fulfilled") {
// 获取回调函数的执行结果
// 根据回调函数的执行结果,改变promise对象的状态
callback(onResolved);
}
if (this.PromiseState === "rejected") {
callback(onRejected);
}
// 判断 pending 状态
if (this.PromiseState === "pending") {
// 保存回调函数
this.callbacks.push({
// 根据回调函数的执行结果决定状态
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
},
});
}
});
};
5. catch方法-异常穿透与值传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
// 实例化对象
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("ok");
// reject("error");
}, 100);
});
// 第二个参数没有传
p.then()
.then((value) => {
console.log(222);
})
.then((value) => {
console.log(333);
})
.catch((reason) => {
console.warn(reason);
});
</script>
</body>
</html>
// 添加 then 方法
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
};
6. resolve方法封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
const p = Promise.resolve("OK");
const p2 = Promise.resolve(
new Promise((resolve, reject) => {
// resolve("ok");
reject("error");
})
);
const p3 = Promise.resolve(Promise.resolve("oh yeah"));
console.log(p3);
</script>
</body>
</html>
promise.js
// 添加 resolve方法
Promise.resolve = function (value) {
// 返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
// 状态设置成成功
resolve(value);
}
});
};
7. reject 方法封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
const p = Promise.reject("OK");
const p2 = Promise.reject(
new Promise((resolve, reject) => {
// resolve("ok");
reject("fail");
})
);
console.log(p2);
</script>
</body>
</html>
promise.js
// 添加 reject方法
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason);
});
};
8. all 方法封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
const p1 = new Promise((resolve, reject) => {
resolve("ok");
});
const p2 = Promise.resolve("success");
const p3 = Promise.resolve("oh yeah");
// 调用 all 方法
let result = Promise.all([p1, p2, p3]);
console.log(result);
</script>
</body>
</html>
// 添加 all 方法
Promise.all = function (promises) {
// 返回的结果为 promise 对象
return new Promise((resolve, reject) => {
// 声明变量
let count = 0;
let arr = [];
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(v) => {
// 得知对象的状态是成功
// 每个promise对象 都成功
count++;
// 将当前promise对象成功的结果 存入数组中
arr[i] = v;
// 判断
if (count === promises.length) {
// 修改状态
resolve(arr);
}
},
(r) => {
reject(r);
}
);
}
});
};
9. race 方法封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("ok");
}, 1000);
});
const p2 = Promise.reject("success");
const p3 = Promise.resolve("oh yeah");
// 调用 race 方法
let result = Promise.race([p1, p2, p3]);
console.log(result);
</script>
</body>
</html>
// 添加 race 方法
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
// 谁先运行 谁决定结果
promises[i].then(
(v) => {
// 修改返回对象的状态为 成功
resolve(v);
},
(r) => {
// 修改返回对象的状态为 失败
reject(r);
}
);
}
});
};
10. then方法回调的异步执行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
const p1 = new Promise((resolve, reject) => {
reject("ok");
console.log(111);
});
// 回调函数是异步执行的
p1.then(
(value) => {
console.log(222);
},
(reason) => {
console.log(444);
}
);
console.log(333);
</script>
</body>
</html>
setTimeOut
// 声明构造函数
function Promise(executor) {
// 添加属性
this.PromiseState = "pending";
this.PromiseResult = null;
// 声明属性
this.callbacks = [];
// 保存实例对象的 this 值
const self = this;
// resolve 函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "fulfilled"; // solved
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
setTimeout(() => {
// 调用成功的回调函数
self.callbacks.forEach((item) => {
item.onResolved(data);
});
});
}
// reject 函数
function reject(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "rejected";
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
setTimeout(() => {
// 调用失败的回调函数
self.callbacks.forEach((item) => {
item.onRejected(data);
});
});
}
try {
// 同步调用 执行器函数
executor(resolve, reject);
} catch (error) {
// 修改 promise 对象状态为 失败
reject(error);
}
}
// 添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
const self = this;
// 判断回调函数参数
if (typeof onResolved !== "function") {
onResolved = (value) => value;
}
if (typeof onRejected !== "function") {
onRejected = (reason) => {
throw reason;
};
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type) {
try {
let result = type(self.PromiseResult);
if (result instanceof Promise) {
result.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
// 调用回调函数 PromiseState
if (this.PromiseState === "fulfilled") {
// 获取回调函数的执行结果
// 根据回调函数的执行结果,改变promise对象的状态
setTimeout(() => {
callback(onResolved);
});
}
if (this.PromiseState === "rejected") {
setTimeout(() => {
callback(onRejected);
});
}
// 判断 pending 状态
if (this.PromiseState === "pending") {
// 保存回调函数
this.callbacks.push({
// 根据回调函数的执行结果决定状态
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
},
});
}
});
};
11. class 版本的实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>初始化结构搭建</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
// const p1 = new Promise((resolve, reject) => {
// setTimeout(() => {
// reject("error");
// // resolve("ok");
// // throw "ERROR";
// });
// });
// // 回调函数是异步执行的
// p1.then(
// (value) => {
// console.log(value);
// },
// (reason) => {
// console.warn(reason);
// }
// );
console.log(Promise.resolve("OK"));
</script>
</body>
</html>
class Promise {
// 构造方法
constructor(executor) {
// 添加属性
this.PromiseState = "pending";
this.PromiseResult = null;
// 声明属性
this.callbacks = [];
// 保存实例对象的 this 值
const self = this;
// resolve 函数
function resolve(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "fulfilled"; // solved
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
setTimeout(() => {
// 调用成功的回调函数
self.callbacks.forEach((item) => {
item.onResolved(data);
});
});
}
// reject 函数
function reject(data) {
// 判断状态
if (self.PromiseState !== "pending") return;
// 1. 修改对象的状态 (PromiseState)
self.PromiseState = "rejected";
// 2. 设置对象的结果值 (PromiseResult)
self.PromiseResult = data;
setTimeout(() => {
// 调用失败的回调函数
self.callbacks.forEach((item) => {
item.onRejected(data);
});
});
}
try {
// 同步调用 执行器函数
executor(resolve, reject);
} catch (error) {
// 修改 promise 对象状态为 失败
reject(error);
}
}
// then 方法封装
then(onResolved, onRejected) {
const self = this;
// 判断回调函数参数
if (typeof onResolved !== "function") {
onResolved = (value) => value;
}
if (typeof onRejected !== "function") {
onRejected = (reason) => {
throw reason;
};
}
return new Promise((resolve, reject) => {
// 封装函数
function callback(type) {
try {
let result = type(self.PromiseResult);
if (result instanceof Promise) {
result.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
// 调用回调函数 PromiseState
if (this.PromiseState === "fulfilled") {
// 获取回调函数的执行结果
// 根据回调函数的执行结果,改变promise对象的状态
setTimeout(() => {
callback(onResolved);
});
}
if (this.PromiseState === "rejected") {
setTimeout(() => {
callback(onRejected);
});
}
// 判断 pending 状态
if (this.PromiseState === "pending") {
// 保存回调函数
this.callbacks.push({
// 根据回调函数的执行结果决定状态
onResolved: function () {
callback(onResolved);
},
onRejected: function () {
callback(onRejected);
},
});
}
});
}
// catch 方法封装
catch(onRejected) {
return this.then(undefined, onRejected);
}
// 添加 resolve方法
// 不属于实例对象,属于类
static resolve = function (value) {
// 返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
(v) => {
resolve(v);
},
(r) => {
reject(r);
}
);
} else {
// 状态设置成成功
resolve(value);
}
});
};
// 添加 reject方法
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
});
}
// 添加 all 方法
static all(promises) {
// 返回的结果为 promise 对象
return new Promise((resolve, reject) => {
// 声明变量
let count = 0;
let arr = [];
// 遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(
(v) => {
// 得知对象的状态是成功
// 每个promise对象 都成功
count++;
// 将当前promise对象成功的结果 存入数组中
arr[i] = v;
// 判断
if (count === promises.length) {
// 修改状态
resolve(arr);
}
},
(r) => {
reject(r);
}
);
}
});
}
// 添加 race 方法
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
// 谁先运行 谁决定结果
promises[i].then(
(v) => {
// 修改返回对象的状态为 成功
resolve(v);
},
(r) => {
// 修改返回对象的状态为 失败
reject(r);
}
);
}
});
}
}
附录:
为什么 function callback
要写在 return
里面?不能直接写在 const self = this
下面?
比如你这样写:
Promise.prototype.then = function (onResolved, onRejected) {
const self = this;
function callback(type) {
console.log("callback created");
}
return new Promise((resolve, reject) => {
// use callback here
});
};
那每次执行 then
,哪怕还没 return
出新 Promise,callback 都已经生成了,这不是很浪费吗?
而放到 return
里面,就变成用的时候才生成,而且每次都是最新的一份!
总结一句话:
因为 callback 只属于 return 的新 Promise,所以放在 return 里面,既避免污染作用域,又节省内存,还保证每次都是干净独立的 callback。
1. callback
是谁要用?
callback
是 return new Promise(...)
里传进去的回调函数用的。
只有 new 的这个 Promise 需要用到 callback
。
如果你把 callback
写在 then
方法最外层(self
下面),这个函数就一直存在于整个 then
方法作用域里了,不管你调不调用 then
,它都会跟着实例走,占用内存。
但是实际上:
-
只有
then
调用时才需要生成一个新的 Promise,才需要用到这个callback
。 -
每次
then
都应该是独立的新逻辑、新 callback。
2. 作用域更干净、清晰
如果写在 return
的里面:
-
每次调用
then
,都会重新生成一个新的callback
。 -
不会污染外部作用域。
-
每个 Promise 的 then 都有自己独立的 callback,不串逻辑。
如果放在外面,就相当于共用同一个 callback 函数,而 Promise 的 then 应该是链式独立的,不能共享内部细节。