Promise

22 阅读2分钟

Promise

Promise是一个构造函数,是异步编程的一种解决方案,通过Promise对象我们可以获取异步操作的消息。而Promise最主要的特性就是:链式调用状态转换错误处理

Promise有三种状态:panding(进行中)、fulfilled(已成功)、rejected(已失败)。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,就不会再变了,会一直保持这个结果。

链式调用指通过.then().catch()方法将多个Promise操作连接起来,使得每个Promise的解决成功(fulfilled)或失败(rejected)值可以被传递给下一个.then().catch()方法进行处理。

在Promise中,错误处理通常通过.catch()方法来实现,它允许你指定一个回调函数来处理Promise链中发生的任何错误,你可以在一个集中的地方处理所有可能出现的错误。

基本用法

const promise = new Promise((resolve, reject) => {
    resolve('成功');
});

promise.then(result => {
    console.log(result); // 输出:成功
    return '下一步';
}).then(nextResult => {
    console.log(nextResult); // 输出:下一步
}).catch(error => {
    console.error(error);
}).finally(() => {
    console.log('执行完成'); // 无论成功或失败都会执行
})

Promise 静态方法

const promise = Promise.resolve('成功');
promise.then(result => console.log(result)); // 输出:成功
const promise = Promise.reject('失败');
promise.catch(error => console.error(error)); // 输出:失败
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.reject('错误');
 
 
Promise.all([p1, p2, p3])
.then(results => console.log(results))
.catch(error => console.error(error)); // 输出:错误

手写Promise

function MyPromise(executor) {
    this.status = 'pending'; // 初始状态为pending  
    this.value = undefined; // 用于保存异步操作的结果  
    this.errMsg = undefined; // 用于保存异步操作失败的原因  
    this.onFulfilledCallbacks = []; // 成功回调函数队列  
    this.onRejectedCallbacks = []; // 失败回调函数队列  

    // 立即执行executor函数,传入resolve和reject函数  
    const resolve = (value) => {
        if (this.status !== 'pending') return;
        this.status = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(callback => callback());
    };

    const reject = (errMsg) => {
        if (this.status !== 'pending') return;
        this.status = 'rejected';
        this.errMsg = errMsg;
        this.onRejectedCallbacks.forEach(callback => callback());
    };

    // 捕获executor函数中抛出的异常  
    try {
        executor(resolve, reject);
    } catch (error) {
        reject(error);
    }
}

// then方法,用于指定Promise成功或失败时要执行的回调函数  
MyPromise.prototype.then = function (onFulfilled, onRejected) {
    const promise2 = new MyPromise((resolve, reject) => {
        // 处理Promise状态为fulfilled的情况  
        if (this.status === 'fulfilled') {
            setTimeout(() => {
                try {
                    const result = onFulfilled(this.value);
                    resolve(result);
                } catch (error) {
                    reject(error);
                }
            }, 0);
        }
        // 处理Promise状态为rejected的情况  
        else if (this.status === 'rejected') {
            setTimeout(() => {
                try {
                    const result = onRejected(this.errMsg);
                    resolve(result);
                } catch (error) {
                    reject(error);
                }
            }, 0);
        }
        // 如果Promise状态还为pending,则将其回调函数加入队列中  
        else {
            this.onFulfilledCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        const result = onFulfilled(this.value);
                        resolve(result);
                    } catch (error) {
                        reject(error);
                    }
                }, 0);
            });
            this.onRejectedCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        const result = onRejected(this.errMsg);
                        resolve(result);
                    } catch (error) {
                        reject(error);
                    }
                }, 0);
            });
        }
    });
    return promise2;
};

// 静态方法resolve,用于将现有值转换为Promise对象  
MyPromise.resolve = function (value) {
    return new MyPromise(resolve => {
        resolve(value);
    });
};

// 静态方法reject,用于返回一个带有拒绝理由的Promise对象  
MyPromise.reject = function (errMsg) {
    return new MyPromise((_, reject) => {
        reject(errMsg);
    });
};

// 使用示例
const promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功!');
    }, 1000);
});

promise.then(
    value => console.log(value), // 输出 '成功!'
    errMsg => console.log(errMsg) // 不会执行
);
MyPromise.resolve(123).then(res => {
    console.log(res);
})
MyPromise.reject('失败!').then(
    value => console.log(value), // 不会执行
    errMsg => console.log(errMsg) // 输出 '失败!'
)