MyPromise

文章介绍了如何创建一个简化版的Promise类,包括构造函数、resolve和reject函数,以及then和catch方法的实现。通过一个异步函数asyncOperation的示例,展示了如何使用MyPromise处理异步操作的成功和失败情况。
摘要由CSDN通过智能技术生成

class MyPromise {  // 创建一个名为 MyPromise 的类
    constructor(executor) {  // 创建 Promise 对象时,传入构造函数的执行器函数会立即执行
        this.status = 'pending';  // 初始化 Promise 的状态为 'pending'
        this.value = undefined;  // 初始化结果值为 undefined
        this.error = undefined;  // 初始化错误信息为 undefined
        this.onResolvedCallbacks = [];  // 存储注册的成功回调函数的数组
        this.onRejectedCallbacks = [];  // 存储注册的失败回调函数的数组

        const resolve = (value) => {  // 定义一个 resolve 函数,用于改变 Promise 的状态为 'fulfilled'
            if (this.status === 'pending') {  // 只有在状态为 'pending' 时才能改变状态
                this.status = 'fulfilled';  // 改变状态为 'fulfilled'
                this.value = value;  // 存储结果值
                this.onResolvedCallbacks.forEach(callback => callback(value));  // 执行已注册的成功回调函数
            }
        };

        const reject = (error) => {  // 定义一个 reject 函数,用于改变 Promise 的状态为 'rejected'
            if (this.status === 'pending') {  // 只有在状态为 'pending' 时才能改变状态
                this.status = 'rejected';  // 改变状态为 'rejected'
                this.error = error;  // 存储错误信息
                this.onRejectedCallbacks.forEach(callback => callback(error));  // 执行已注册的失败回调函数
            }
        };

        try {  // 尝试执行执行器函数 创建 Promise 对象时,传入构造函数的执行器函数会立即执行。
            executor(resolve, reject);  // 将 resolve 和 reject 函数作为参数传递给执行器函数。
        } catch (error) {  // 如果执行器函数中抛出了异常,则将 Promise 的状态改为 'rejected'
            reject(error);  // 改变状态为 'rejected',并传入错误信息
        }
    }

    then(onResolved, onRejected) {  // 注册处理成功和失败的回调函数
        const newPromise = new MyPromise((resolve, reject) => {  // 创建一个新的 Promise 对象
            if (this.status === 'fulfilled') {  // 如果当前 Promise 的状态为 'fulfilled'
                try {
                    const result = onResolved(this.value);  // 执行成功回调函数,并获取返回值
                    resolve(result);  // 将返回值作为结果传递给新的 Promise 对象的 resolve 函数
                } catch (error) {
                    reject(error);  // 如果成功回调函数抛出异常,则将异常作为错误信息传递给新的 Promise 对象的 reject 函数
                }
            } else if (this.status === 'rejected') {  // 如果当前 Promise 的状态为 'rejected'
                try {
                    const result = onRejected(this.error);  // 执行失败回调函数,并获取返回值
                    resolve(result);  // 将返回值作为结果传递给新的 Promise 对象的 resolve 函数
                } catch (error) {
                    reject(error);  // 如果失败回调函数抛出异常,则将异常作为错误信息传递给新的 Promise 对象的 reject 函数
                }
            } else {  // 如果当前 Promise 的状态为 'pending'
                this.onResolvedCallbacks.push((value) => {  // 将成功回调函数加入到回调函数数组中
                    try {
                        const result = onResolved(value);  // 执行成功回调函数,并获取返回值
                        resolve(result);  // 将返回值作为结果传递给新的 Promise 对象的 resolve 函数
                    } catch (error) {
                        reject(error);  // 如果成功回调函数抛出异常,则将异常作为错误信息传递给新的 Promise 对象的 reject 函数
                    }
                });

                this.onRejectedCallbacks.push((error) => {  // 将失败回调函数加入到回调函数数组中
                    try {
                        const result = onRejected(error);  // 执行失败回调函数,并获取返回值
                        resolve(result);  // 将返回值作为结果传递给新的 Promise 对象的 resolve 函数
                    } catch (error) {
                        reject(error);  // 如果失败回调函数抛出异常,则将异常作为错误信息传递给新的 Promise 对象的 reject 函数
                    }
                });
            }
        });

        return newPromise;  // 返回新的 Promise 对象,用于链式调用
    }

    catch(onRejected) {  // 注册处理失败的回调函数(简化版的 then 方法)
        return this.then(null, onRejected);  // 调用 then 方法,传入 null 作为成功回调函数,传入 onRejected 作为失败回调函数
    }
}

/**
这是一个简化版的 Promise 类,具体的功能包括状态管理、异步操作的承诺和回调函数的注册。现在我们来分析一下这个实现的原理:

1, 构造函数:构造函数接受一个执行器函数 executor,并初始化 Promise 的初始状态为 'pending',结果值 value 和错误信息 error 都设置为 undefined。同时,定义两个空数组 onResolvedCallbacks 和 onRejectedCallbacks 用于存储注册的回调函数。

2, resolve 和 reject:分别是两个内部函数,用于将 Promise 的状态从 'pending' 改变为 'fulfilled' 或 'rejected'。当状态改变时,执行注册的回调函数,并传递相应的结果值或错误信息。

3, try-catch 块:在构造函数中执行 executor 函数,传入 resolve 和 reject 作为参数。使用 try-catch 块来处理执行器函数中可能出现的异常情况,如果出现异常,则将 Promise 的状态改为 'rejected'。

4, then 方法:用于注册处理 Promise 成功或失败的回调函数。返回一个新的 Promise 对象供链式调用。在 then 方法中,根据当前 Promise 的状态进行不同的处理:

    ●如果状态为 'fulfilled',则立即执行 onResolved 回调函数,并将结果传递给新的 Promise 对象的 resolve 函数;
    ●如果状态为 'rejected',则立即执行 onRejected 回调函数,并将错误信息传递给新的 Promise 对象的 reject 函数;
    ●如果状态为 'pending',则将 onResolved 和 onRejected 回调函数分别添加到数组 onResolvedCallbacks 和 onRejectedCallbacks 中,等待异步操作完成后执行。
5,catch 方法:是 then 方法的简化版本,用于注册处理 Promise 失败的回调函数。实际上就是调用 then 方法,传入 null 作为 onResolved 参数,而 onRejected 参数则为处理失败回调的函数。

这个简化版的 Promise 类的原理和实现比较简单,仅涵盖了基本的异步操作状态管理和回调函数注册的功能。实际上,标准的 Promise 类还包括更多功能,如异步操作的并行执行、顺序执行、错误冒泡和链式调用等。如果有需要,可以在这个基础上继续扩展。
 */

//----------------------------------------



// 创建一个返回 MyPromise 的异步函数。
function asyncOperation() {

    return new MyPromise((resolve, reject) => {
        setTimeout(() => {
            const randomNumber = Math.random();

            if (randomNumber >= 0.5) {
                resolve(randomNumber);  // 模拟异步操作成功,将随机数作为结果传递给 resolve
            } else {
                reject(new Error('Operation failed'));  // 模拟异步操作失败,将错误对象传递给 reject
            }
        }, 1000);
    });
}

// 使用 MyPromise 调用异步函数并处理结果
asyncOperation()        //asyncOperation会立即返回一个MyPromise 对象
    .then(result => {   //then会立即被调用,then是用来注册回调函数的
        console.log('Async operation succeeded:', result);
    })
    .catch(error => {
        //console.error('Async operation failed:哈哈', error);
        console.error('出错了!出错了!');
    });

/**
在上面的示例中,我们创建了一个返回 MyPromise 对象的异步函数 asyncOperation。该函数模拟了一个异步操作,延迟1秒后随机生成一个数字,并根据数字的大小决定是成功还是失败。

然后,我们使用 MyPromise 调用异步函数,并通过 .then() 注册了一个成功回调函数和一个 .catch() 注册了一个失败回调函数。当异步操作成功时,成功回调函数会被执行,并且结果值将作为参数传递给回调函数。当异步操作失败时,失败回调函数会被执行,并且错误对象将作为参数传递给回调函数。

你可以根据实际情况在 .then() 和 .catch() 中添加适当的逻辑来处理异步操作的结果。

希望这个例子能够帮助你理解如何使用 MyPromise。
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值