Skip to content

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

alt text 从 chrome 里面可以看到 promise 有 PromiseState 和 PromiseResult 两个变量,有 原型方法catch、finally、then、静态方法race、all、resolve、reject

  1. 所以整体的设计为
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() {

}
  1. 当执行一下代码的时候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)
    })
}