new Promise(() => {});
Promise 有三种状态
成功 fulfilled失败 rejected等待 pending状态改变:pending -> fulfilled 或 pending -> rejected一旦状态确定就不可更改resolve 和 reject 函数是用来更改状态的
resolve:fulfilledreject:rejectednew Promise((resolve, reject) => {
resolve("成功");
reject("失败");
});
1.2 创建 Promise 原理代码
1.2.1 执行器
new Promise((resolve, reject) => {
resolve("成功");
reject("失败");
});
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
// 立即执行
executor(this.resolve, this.reject);
}
// promise 状态
status = PENDING;
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = () => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
};
reject = () => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
};
}
1.2.2 then
then 方法内部做的事情就是判断状态如果状态是成功,调用成功回调函数。如果状态是失败,调用失败回调函数then 方法是被定义在原型对象中的then 成功回调有一个参数,表示成功之后的值。then 失败回调有一个参数,表示失败后的原因
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
resolve("成功");
reject("失败");
});
promise.then(
(value) => {},
(reason) => {}
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
// 立即执行
executor(this.resolve, this.reject);
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined; -- 【新增】
// 失败后的原因
reason = undefined; -- 【新增】
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => { -- 【新增参数】
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value; -- 【新增】
};
reject = (reason) => { -- 【新增参数】
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason; -- 【新增】
};
then(successCallback, failCallback) { -- 【新增】
// 判断状态
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
}
}
}
module.exports = MyPromise;
二、在 Promise 类中加入异步逻辑
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => { -- 【新增】
resolve("成功");
}, 2000);
// reject("失败");
});
// 此处 then 方法是立即执行,因为定时器的存在,无法判断状态
// 所以,先将这两个回调函数存贮起来
// 在resolve 或 reject 调用时,判断回调函数是否存在,如果存在,就执行
promise.then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
}
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = undefined; -- 【新增】
// 失败回调
failCallback = undefined; -- 【新增】
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
this.successCallback && this.successCallback(this.value); -- 【新增】
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
this.failCallback && this.failCallback(this.reason); -- 【新增】
};
then(successCallback, failCallback) {
// 判断状态
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else { -- 【新增】
// 等待
// 将成功回调和失败回调存储起来
this.successCallback = successCallback;
this.failCallback = failCallback;
}
}
}
module.exports = MyPromise;
三、实现 then 方法多次调用添加多个处理函数
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("成功");
}, 2000);
// reject("失败");
});
promise.then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
}
);
promise.then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
}
);
promise.then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
}
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = []; -- 【修改】
// 失败回调
failCallback = []; -- 【修改】
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) { -- 【新增】
this.successCallback.shift()(this.value);
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) { -- 【新增】
this.failCallback.shift()(this.reason);
}
};
then(successCallback, failCallback) {
// 判断状态
if (this.status === FULFILLED) {
successCallback(this.value);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback); -- 【修改】
this.failCallback.push(failCallback); -- 【修改】
}
}
}
module.exports = MyPromise;
四、实现 then 方法的链式调用
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
resolve("成功");
// reject("失败");
});
function other() {
return new MyPromise((resolve, reason) => {
resolve("other");
});
}
promise
.then((value) => {
console.log(value);
return other();
})
.then((value) => {
console.log(value);
});
//成功
// other
原理代码:‘
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()(this.value);
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()(this.reason);
}
};
then(successCallback, failCallback) { -- 【调整】
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(x, resolve, reject);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
});
return promise2;
}
}
function resolvePromise(x, resolve, reject) { -- 【新增】
if (x instanceof MyPromise) {
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
五、then 方法链式调用识别 Promise 对象自返回
Promise 自己返回自己会报错,需要处理这种错误
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
resolve("成功");
// reject("失败");
});
let p1 = promise.then((value) => {
console.log(value);
return p1;
});
p1.then(
(value) => {
console.log(value);
},
(reason) => {
console.log(reason);
// TypeError: Chaining cycle detected for promise #
}
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject);
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()(this.value);
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()(this.reason);
}
};
then(successCallback, failCallback) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中,
// 所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => { -- 【调整】
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
}, 0);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) { -- 【新增】
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
六、捕获错误及 then 链式调用其他状态代码补充
6.1 捕获错误
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
// throw new Error("executor error");
resolve("成功");
// reject("失败");
});
promise
.then(
(value) => {
console.log(value);
throw new Error("then error");
},
(reason) => {
console.log(reason.message); // executor error(第一个执行器错误)
}
)
.then(
(value) => {
console.log(value);
},
(reason) => {
// 上一个 then 的回调函数的错误需要在这个 then 中查看
console.log(reason.message);
}
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try { -- 【捕获执行器错误】
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()(this.value);
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()(this.reason);
}
};
then(successCallback, failCallback) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中
//所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try { -- 【捕获then回调函数错误】
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
failCallback(this.reason);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
6.2 then 链式调用其他状态代码补充
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve("成功");
}, 2000);
// reject("失败");
});
promise
.then(
(value) => {
console.log(value); // "成功"
return "aaa";
},
(reason) => {
console.log(reason);
}
)
.then((value) => {
console.log(value); // "aaa"
});
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()(); -- 【取消shift参数】
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()(); -- 【取消shift参数】
}
};
then(successCallback, failCallback) {
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中
//所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => { -- 【修改】
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failCallback.push(() => { -- 【修改】
etTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
七、将 then 方法的参数变成可选参数
测试用例:
const MyPromise = require("./myPromise.js");
let promise = new MyPromise((resolve, reject) => {
// resolve("成功");
reject("失败");
});
promise
.then()
.then()
.then(
(value) => {
console.log(value);
},
(reason) => console.log(reason) // 失败
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()();
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()();
}
};
then(successCallback, failCallback) {
successCallback = successCallback ? successCallback : (value) => value;
failCallback = failCallback --【新增】
? failCallback
: (reason) => {
throw reason;
};
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中,
// 所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
八、Promise.all 方法的实现
测试用例:
const MyPromise = require("./myPromise.js");
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(() => {
resolve("p1");
}, 2000);
});
}
function p2() {
return new MyPromise(function (resolve, reject) {
resolve("p1");
});
}
MyPromise.all(["a", "b", p1(), p2(), "c"]).then(
(result) => console.log(result)
// [ 'a', 'b', 'p1', 'p1', 'c' ]
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()();
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()();
}
};
then(successCallback, failCallback) {
// 当then没有回调函数时,为了传递状态,需要我们手动添加一个回调
successCallback = successCallback ? successCallback : (value) => value;
failCallback = failCallback
? failCallback
: (reason) => {
throw reason;
};
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中,
// 所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
static all(array) { --【新增】
let result = [];
let index = 0; // 防止出现异步空值
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then(
(value) => addData(i, value),
(reason) => reject(reason)
);
} else {
// 普通值
addData(i, array[i]);
}
}
});
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
九、Promise.resolve 方法的实现
测试用例:
const MyPromise = require("./myPromise.js");
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(() => {
resolve("p1");
}, 2000);
});
}
MyPromise.resolve(100).then((value) => console.log(value)); // 100
MyPromise.resolve(p1()).then((value) => console.log(value)); // "p1"
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()();
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()();
}
};
then(successCallback, failCallback) {
// 当then没有回调函数时,为了传递状态,需要我们手动添加一个回调
successCallback = successCallback ? successCallback : (value) => value;
failCallback = failCallback
? failCallback
: (reason) => {
throw reason;
};
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中,
// 所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
static all(array) {
let result = [];
let index = 0; // 防止出现异步空值
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then(
(value) => addData(i, value),
(reason) => reject(reason)
);
} else {
// 普通值
addData(i, array[i]);
}
}
});
}
static resolve(value) { -- 【新增】
if (value instanceof MyPromise) return value;
return new MyPromise((resolve) => resolve(value));
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
十、Promise.finally 方法的实现
不管 promise 最后的状态,在执行完 then 或 catch 指定的回调函数以后,都会执行 finally 方法指定的回调函数在 finally 方法后面,可以链式调用 then 方法拿到当前 promise 最终返回的结果定义在 promise 原型对象上
测试用例:
const MyPromise = require("./myPromise.js");
function p1() {
return new MyPromise(function (resolve, reject) {
setTimeout(() => {
resolve("p1");
}, 2000);
});
}
function p2() {
return new MyPromise(function (resolve, reject) {
resolve("p2");
});
}
p2()
.finally(() => {
console.log("finally");
return p1();
})
.then(
(value) => {
console.log(value); // "p2"
},
(reason) => {
console.log(reason);
}
);
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()();
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()();
}
};
then(successCallback, failCallback) {
// 当then没有回调函数时,为了传递状态,需要我们手动添加一个回调
successCallback = successCallback ? successCallback : (value) => value;
failCallback = failCallback
? failCallback
: (reason) => {
throw reason;
};
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中,
// 所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
finally(callback) { -- 【新增】
return this.then(
(value) => {
return MyPromise.resolve(callback()).then(() => value);
},
(reason) => {
return MyPromise.resolve(callback()).then(() => {
throw reason;
});
}
);
}
static all(array) {
let result = [];
let index = 0; // 防止出现异步空值
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then(
(value) => addData(i, value),
(reason) => reject(reason)
);
} else {
// 普通值
addData(i, array[i]);
}
}
});
}
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise((resolve) => resolve(value));
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
十一、catch 方法的实现
测试用例:
const MyPromise = require("./myPromise.js");
function p2() {
return new MyPromise(function (resolve, reject) {
reject("失败");
});
}
p2()
.then((value) => console.log(value))
.catch((reason) => console.log(reason));
原理代码:
const PENDING = "pending"; // 等待
const FULFILLED = "fulfilled"; // 成功
const REJECTED = "rejected"; // 失败
class MyPromise {
constructor(executor) {
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
// promise 状态
status = PENDING;
// 成功后的值
value = undefined;
// 失败后的原因
reason = undefined;
// 成功回调
successCallback = [];
// 失败回调
failCallback = [];
// 此处使用箭头函数,是为了让这个函数内部的 this 指向类的对象
resolve = (value) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为成功
this.status = FULFILLED;
// 保存成功之后的值
this.value = value;
// 判断成功回调是否存在,如果存在则调用
// this.successCallback && this.successCallback(this.value); -- 【失效】
while (this.successCallback.length) {
this.successCallback.shift()();
}
};
reject = (reason) => {
// 如果状态不是等待,阻止程序向下执行
if (this.status !== PENDING) return;
// 将状态更改为失败
this.status = REJECTED;
// 保存失败原因
this.reason = reason;
// 判断失败回调是否存在,如果存在则调用
// this.failCallback && this.failCallback(this.reason); -- 【失效】
while (this.failCallback.length) {
this.failCallback.shift()();
}
};
then(successCallback, failCallback) {
// 当then没有回调函数时,为了传递状态,需要我们手动添加一个回调
successCallback = successCallback ? successCallback : (value) => value;
failCallback = failCallback
? failCallback
: (reason) => {
throw reason;
};
let promise2 = new MyPromise((resolve, reject) => {
// 判断状态
if (this.status === FULFILLED) {
// 因为 promise2 是在new MyPromise 的执行器中,
// 所以必须将其变成异步代码,才能将 promise2 获取到
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
// 等待
// 将成功回调和失败回调存储起来
this.successCallback.push(() => {
setTimeout(() => {
try {
let x = successCallback(this.value);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.failCallback.push(() => {
setTimeout(() => {
try {
let x = failCallback(this.reason);
// 判断 x 的值是普通值还是 promise 对象
// 如果是普通值,直接调用 resolve
// 如果是 promise 对象,查看 promise 对象返回的结果
// 再根据 promise 对象返回的结果,决定调用 resolve 还是 reject
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
finally(callback) {
return this.then(
(value) => {
return MyPromise.resolve(callback()).then(() => value);
},
(reason) => {
return MyPromise.resolve(callback()).then(() => {
throw reason;
});
}
);
}
catch(failCallback) { -- 【新增】
return this.then(undefined, failCallback);
}
static all(array) {
let result = [];
let index = 0; // 防止出现异步空值
return new MyPromise((resolve, reject) => {
function addData(key, value) {
result[key] = value;
index++;
if (index === array.length) {
resolve(result);
}
}
for (let i = 0; i < array.length; i++) {
let current = array[i];
if (current instanceof MyPromise) {
// promise 对象
current.then(
(value) => addData(i, value),
(reason) => reject(reason)
);
} else {
// 普通值
addData(i, array[i]);
}
}
});
}
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise((resolve) => resolve(value));
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x instanceof MyPromise) {
if (promise2 === x) {
return reject(
new TypeError("Chaining cycle detected for promise #" )
);
}
// promise 对象
// x.then(value => resolve(value),reason => reject(reason))
x.then(resolve, reject);
} else {
// 普通值
resolve(x);
}
}
module.exports = MyPromise;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)