当前位置: 首页 > news >正文

JavaScript中Promise详解

Promise 是 JavaScript 中用于处理异步操作的对象。它代表一个异步操作的最终完成及其结果值。Promise 提供了一种更优雅的方式来处理异步代码,避免了传统的回调地狱。

1. Promise 的基本概念

Promise 有三种状态:

1. Pending(等待中):初始状态,既不是成功,也不是失败;

2. Fulfilled(已成功):操作成功完成;

3. Rejected(已失败):操作失败;

Promise 的状态一旦改变,就不会再变。即从 Pending 变为 Fulfilled 或 Rejected 后,状态就固定了。

2. 创建 Promise

你可以通过 new Promise() 构造函数来创建一个 Promise 对象。构造函数接受一个函数作为参数,这个函数有两个参数:resolve 和 reject,它们都是函数。

1. resolve(value):将 Promise 的状态从 Pending 变为 Fulfilled,并将 value 作为成功的结果;

2. reject(reason):将 Promise 的状态从 Pending 变为 Rejected,并将 reason 作为失败的原因;

const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve("操作成功!");
        } else {
            reject("操作失败!");
        }
    }, 1000);
})

3. 使用 Promise

Promise 对象有两个主要的方法来处理成功和失败的情况:.then() 和 .catch()。

1. .then(onFulfilled, onRejected):当 Promise 状态变为 Fulfilled 时,调用 onFulfilled 函数;当状态变为 Rejected 时,调用 onRejected 函数;

2. .catch(onRejected):当 Promise 状态变为 Rejected 时,调用 onRejected 函数;

myPromise
    .then((result) => {
        console.log(result); // 输出: 操作成功!
    })
    .catch((error) => {
        console.error(error); // 输出: 操作失败!
    });

4. Promise 链式调用

Promise 支持链式调用,即在一个 .then() 中返回一个新的 Promise,然后可以在下一个 .then() 中继续处理。

new Promise((resolve, reject) => {
    setTimeout(() => resolve(1), 1000);
})
.then((result) => {
    console.log(result); // 输出: 1
        return result * 2;
})
.then((result) => {
    console.log(result); // 输出: 2
    return result * 2;
})
.then((result) => {
    console.log(result); // 输出: 4
});

5. Promise 的静态方法

Promise 还提供了一些静态方法来处理多个 Promise 对象:

1. Promise.all(iterable):接受一个 Promise 对象的数组,当所有 Promise 都成功时,返回一个包含所有结果的数组;如果有一个 Promise 失败,则立即返回失败的结果;


Promise.all([promise1, promise2, promise3])
    .then((results) => {
        console.log(results); // 所有 Promise 成功的结果数组
    })
    .catch((error) => {
        console.error(error); // 第一个失败的 Promise 的错误
    });

2. Promise.race(iterable):接受一个 Promise 对象的数组,返回第一个完成(无论成功或失败)的 Promise 的结果;

Promise.race([promise1, promise2, promise3])
    .then((result) => {
        console.log(result); // 第一个完成的 Promise 的结果
    })
    .catch((error) => {
        console.error(error); // 第一个失败的 Promise 的错误
    });

3. Promise.resolve(value):返回一个以给定值解析的 Promise 对象;

Promise.resolve("成功").then((result) => {
    console.log(result); // 输出: 成功
});

4. Promise.reject(reason):返回一个以给定原因拒绝的 Promise 对象;

Promise.reject("失败").catch((error) => {
    console.error(error); // 输出: 失败
});

6. 手写 Promise 实现

下面是一个手写的简单 Promise 实现,包含了 resolve 和 reject 的基本功能。这个实现是一个简化版,仅用于理解 Promise 的核心原理,并不完全符合官方 Promise 的规范。

class MyPromise {
    constructor(executor) {
        this.status = 'pending'; // 初始状态为 pending
        this.value = undefined;  // 存储成功的结果
        this.reason = undefined; // 存储失败的原因
        this.onFulfilledCallbacks = []; // 存储成功的回调函数
        this.onRejectedCallbacks = [];  // 存储失败的回调函数

        // resolve 函数
        const resolve = (value) => {
            if (this.status === 'pending') {
                this.status = 'fulfilled'; // 状态改为 fulfilled
                this.value = value; // 存储成功的结果
                // 执行所有成功的回调
                this.onFulfilledCallbacks.forEach((fn) => fn());
            }
        };

        // reject 函数
        const reject = (reason) => {
            if (this.status === 'pending') {
                this.status = 'rejected'; // 状态改为 rejected
                this.reason = reason;     // 存储失败的原因
                // 执行所有失败的回调
                this.onRejectedCallbacks.forEach((fn) => fn());
            }
        };

        // 执行 executor,传入 resolve 和 reject
        try {
            executor(resolve, reject);
        } catch (error) {
            reject(error); // 如果 executor 抛出异常,直接 reject
        }
    }

    // then 方法
    then(onFulfilled, onRejected) {
        if (this.status === 'fulfilled') {
            // 如果状态已经是 fulfilled,直接执行 onFulfilled
            onFulfilled(this.value);
        } else if (this.status === 'rejected') {
            // 如果状态已经是 rejected,直接执行 onRejected
            onRejected(this.reason);
        } else if (this.status === 'pending') {
            // 如果状态是 pending,将回调函数存储起来
            this.onFulfilledCallbacks.push(() => onFulfilled(this.value));
            this.onRejectedCallbacks.push(() => onRejected(this.reason));
        }
    }

    // catch 方法
    catch(onRejected) {
        return this.then(null, onRejected);
    }
}

6.1. 使用示例

// 创建一个 MyPromise
const myPromise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve("操作成功!");
        } else {
            reject("操作失败!");
        }
    }, 1000);
});

// 使用 then 和 catch 处理结果
myPromise
    .then((result) => {
        console.log(result); // 输出: 操作成功!
    })
    .catch((error) => {
        console.error(error); // 输出: 操作失败!
    });

6.2. 功能说明

1. 状态管理

status 用于记录当前 Promise 的状态,初始为 pending。

当调用 resolve 时,状态变为 fulfilled,并存储成功的结果 value。

当调用 reject 时,状态变为 rejected,并存储失败的原因 reason。

2. 回调队列

如果 Promise 的状态是 pending,则将 then 中的回调函数存储到 onFulfilledCallbacks 或 onRejectedCallbacks 中。

当状态改变时,依次执行对应的回调函数。

3. 异常处理

如果 executor 函数中抛出异常,会直接调用 reject。

4. 链式调用

当前实现是一个简化版,不支持链式调用(即 then 返回一个新的 Promise)。完整的 Promise 实现需要支持链式调用。

6.3. 进一步优化

如果需要实现完整的 Promise 功能,还需要支持以下特性:

1. 链式调用:then 方法需要返回一个新的 Promise;

2. 值穿透:如果 then 的参数不是函数,需要实现值穿透;

3. 微任务队列:then 的回调函数需要放入微任务队列中执行(可以使用 queueMicrotask 或 setTimeout 模拟);

7. async/await

async/await 是 ES2017 引入的语法糖,用于更简洁地处理 Promise。async 函数返回一个 Promise,而 await 用于等待 Promise 的完成

async function myAsyncFunction() {
    try {
        const result = await myPromise;
        console.log(result); // 输出: 操作成功!
    } catch (error) {
        console.error(error); // 输出: 操作失败!
    }
}
myAsyncFunction();

8. 总结

Promise 是 JavaScript 中处理异步操作的重要工具。它通过 .then() 和 .catch() 方法提供了更清晰的代码结构,避免了回调地狱。async/await 进一步简化了 Promise 的使用,使得异步代码看起来更像同步代码。掌握 Promise 的使用对于编写现代 JavaScript 应用程序至关重要。

相关文章:

  • 蓝桥杯2024年第十五届省赛真题-回文数组
  • 数据库之PostgreSQL详解(待补充)
  • 一文了解JVM的垃圾回收
  • BIG_EVENT
  • IDS 和 IPS 日志监控的重要性
  • JVM内存结构笔记05-直接内存
  • 深度学习----激活函数
  • VS Code 配置优化指南
  • 《大语言模型》学习笔记(一)
  • 大数据任务调度:DolphinScheduler、Airflow 实战(调度策略、任务依赖)
  • Swift 手动导入 RxSwift.xcframework 报错
  • python使用venv命令创建虚拟环境(ubuntu22)
  • SpringCloud带你走进微服务的世界
  • 基于Java + Redis + RocketMQ的库存秒杀系统设计与实现
  • Langchain应用-rag优化
  • 微信小程序从右向左无限滚动组件封装(类似公告)
  • 命令设计模式
  • 【计算机网络】第八版和第七版的主要区别,附PDF
  • 【python】不规则字符串模糊匹配(fuzzywuzzy)
  • AI自动化、资本短视、三输与破局
  • 鹤壁做网站哪家便宜/淘宝网官方网站
  • 做传奇网站/各大网站排名
  • 做网站那个平台/西安网站seo排名优化
  • 网站怎么做百度商桥/江苏疫情最新消息
  • 视频网站亏损也做/怎样在百度上发布作品
  • 移动互联网开发就业前景/珠海关键词优化软件