Appearance
Promise
怎么理解Promise
JavaScript 中的 Promise 是一种用于异步计算的对象。它代表了异步操作的最终完成(或失败)及其结果值。Promise 的主要目的是提供一种更合理的方式来处理异步操作,避免了回调函数的嵌套(也称为“回调地狱”),并且使得异步代码的写法更接近于同步代码。
Promise 的三个状态:
- Pending(进行中):初始状态,既不是成功,也不是失败。
- Fulfilled(已成功):意味着操作完成,并且成功。
- Rejected(已失败):意味着操作完成,并且失败。 一个 Promise 对象一旦从 Pending 状态变为 Fulfilled 或 Rejected 状态,就不会再变,这称为状态的不可变性。
promise 使用
js
const myPromise = new Promise((resolve, reject) => {
// 异步操作
if (/* 异步操作成功 */) {
resolve("Success!");
} else {
reject("Error!");
}
});
myPromise.then((value) => {
console.log(value); // "Success!"
}).catch((error) => {
console.error(error); // "Error!"
});手写 promise
从 chrome 里面可以看到 promise 有 PromiseState 和 PromiseResult 两个变量,有 原型方法catch、finally、then、静态方法race、all、resolve、reject
- 所以整体的设计为
js
function MyPromise(executor) {
var _this = this;
this.PromiseState = 'pending';
this.PromiseResult = null;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
}
MyPromise.prototype.catch = function() {
}
MyPromise.prototype.finally = function() {
}
MyPromise.prototype.then = function() {
}
MyPromise.race = function() {
}
MyPromise.all = function() {
}
MyPromise.resolve = function() {
}
MyPromise.reject = function() {
}- 当执行一下代码的时候MyPromise的 prototype 指向了 proto,MyPromise的内部的 this 指向了 p,入参excutor
js
var p = new MyPromise((resolve, reject) => {
resolve('1')
})js
function MyPromise(executor) {
var _this = this;
this.PromiseState = 'pending';
this.PromiseResult = null;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
function resolve(value) {
if (_this.PromiseState === 'pending') {
_this.PromiseState = 'resolved';
_this.PromiseResult = value;
_this.onResolvedCallbacks.forEach(callback => callback(value));
}
}
function reject(reason) {
if (_this.PromiseState === 'pending') {
_this.PromiseState = 'rejected';
_this.reason = reason;
_this.onRejectedCallbacks.forEach(callback => callback(reason));
}
}
try {
executor(resolve, reject); // 立即执行,同步执行执行器中的代码
} catch (error) {
reject(error); // 如果执行器抛出异常,则拒绝 Promise
}
}
// 实现then
MyPromise.prototype.then = function(resolve, reject) {
if (this.PromiseState === 'fulfilled') {
resolve(this.value);
}
if (this.PromiseState === 'rejected') {
reject(this.reason);
}
if (this.PromiseState === 'pending') {
this.onResolvedCallbacks.push(resolve)
this.onRejectedCallbacks.push(reject)
}
}
var p = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 3000)
})
p.then(v => console.log(v)) // 1在实例化的时候调用的 resolve 实际上调用的MyPromise内部的resolve方法所以这里,同理reject的调用实际上是内部的reject方法, 内部的 resolve 会去循环调用onResolvedCallbacks里的函数就是实例 then 的入参,所以这里 then 方法会将 resolve 的回调push 到onResolvedCallbacks里面等到实例化的入参的 resolve 被执行的时候内部的 resolve 被执行就会触发这个 callback,其他的方法类似
js
MyPromise.prototype.catch = function(reject) {
this.then(undefined, reject)
}
MyPromise.prototype.finally = function(fn) {
if (this.PromiseState !== 'pending') {
fn(this.value, this.reason);
}
}
MyPromise.prototype.then = function(resolve, reject) {
if (this.PromiseState === 'fulfilled') {
resolve(this.value);
}
if (this.PromiseState === 'rejected') {
reject(this.reason);
}
if (this.PromiseState === 'pending') {
this.onResolvedCallbacks.push(resolve)
this.onRejectedCallbacks.push(reject)
}
}
MyPromise.race = function(promises) {
return new Promise((resolve,reject)=>{
// 遍历promises,获取每个promise的结果
promises.forEach((p)=>{
Promise.resolve(p).then(
value => {
// 只要有一个成功,返回的promise的状态九尾resolved
resolve(value)
},
reason => { //只要有一个失败,return的promise状态就为reject
reject(reason)
}
)
})
})
}
MyPromise.all = function(promises) {
const values = new Array(promises.length)
var resolvedCount = 0 //计状态为resolved的promise的数量
return new MyPromise((resolve,reject)=>{
// 遍历promises,获取每个promise的结果
promises.forEach((p,index)=>{
p.then(
value => {
// p状态为resolved,将值保存起来
values[index] = value
resolvedCount++;
// 如果全部p都为resolved状态,return的promise状态为resolved
if(resolvedCount === promises.length){
resolve(values)
}
},
reason => { //只要有一个失败,return的promise状态就为reject
reject(reason)
}
)
})
})
}
MyPromise.resolve = function(value) {
return new MyPromise((resolve,reject) => {
if (value instanceof MyPromise){
// 如果value 是promise
value.then(
value => {resolve(value)},
reason => {reject(reason)}
)
} else {
// 如果value不是promise
resolve(value)
}
})
}
MyPromise.reject = function() {
return new Promise((_,reject)=>{
reject(reason)
})
}