跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++大前端算法

基于C++11手写Promise实现

综述由AI生成C++11 环境下手动实现 Promise 模式,通过定义 CProimse 类管理状态、回调及链式调用,模拟前端 Promise 行为。文章对比了自定义实现与标准库 std::promise 在功能、异步支持及链式调用上的差异。结论指出手写实现有助于理解原理,但实际开发推荐使用 std::promise 以获得更好的性能与稳定性保障。

宁静发布于 2026/3/28更新于 2026/5/3118 浏览
基于C++11手写Promise实现

引言

在前端开发中,Promise 是处理异步操作的重要工具。它通过将异步操作封装在 Promise 实例中,解决了传统回调地狱的问题,提高了代码的可读性和可维护性。Promise 的概念并非前端独有,在 C++11 标准中也引入了 std::promise,用于实现类似的功能。

本文将从一个手写的 C++ Promise 实现(基于 C++11)出发,分析其工作原理,并与 std::promise 进行对比,探讨两者的异同点以及适用场景。

前端 Promise 的应用与优势

常见应用场景

定时器 Promise 还可以用于处理定时器,使代码更加直观。

function timeout(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}
timeout(1000).then(() => {
    console.log('1 秒后执行');
});

网络请求 Promise 可以用于处理 AJAX 请求,简化异步数据获取的逻辑。

fetch('https://api.example.com/data').then(response => response.json()).then(data => {
    console.log('获取到数据:', data);
}).catch(error => {
    console.error('请求失败:', error);
});

并发请求

使用 Promise.all 可以同时处理多个异步请求。

const promise1 = fetch('https://api.example.com/data1');
 promise2 = ();
.([promise1, promise2]).( {
     [data1, data2] = responses.( response.());
     .([data1, data2]);
}).( {
    .(, data1, data2);
}).( {
    .(, error);
});
const
fetch
'https://api.example.com/data2'
Promise
all
then
responses =>
const
map
response =>
json
return
Promise
all
then
([data1, data2]) =>
console
log
'两个数据都获取成功:'
catch
error =>
console
error
'至少一个请求失败:'

Promise 解决的问题

  1. 回调地狱:通过链式调用,Promise 解决了传统回调嵌套导致的代码难以阅读和维护的问题。
  2. 错误处理:Promise 提供了统一的错误处理机制,通过 catch 方法可以集中处理所有异步操作中的错误。
  3. 代码可读性:Promise 使得异步代码的逻辑更加清晰,符合同步代码的书写习惯。
  4. 并发控制:通过 Promise.all 和 Promise.race,可以方便地控制多个异步操作的执行顺序和结果。

手写 C++ Promise 实现

类结构与成员变量

template<typename Element>
class CProimse {
private:
    using Resolve = std::function<void(Element)>;
    using Reject = std::function<void(const std::string&)>;
private:
    Element m_element; /**< 异步操作的结果 */
    std::string m_reason; /**< 拒绝的原因 */
    CProimseState m_state; /**< 当前状态 */
    std::list<Resolve> m_resolves; /**< 成功回调函数列表 */
    std::list<Reject> m_rejects; /**< 失败回调函数列表 */
public:
    CProimse();
    void reject(const std::string& reason);
    void resolve(Element element);
    void onCatch(const Reject& rej);
    CProimse* then(const Resolve& res);
};
  • Resolve 和 Reject:定义了成功和失败回调函数的类型。
  • m_element 和 m_reason:分别存储 Promise 的结果和拒绝原因。
  • m_state:表示 Promise 的当前状态,初始状态为 PENDING。
  • m_resolves 和 m_rejects:存储注册的成功和失败回调函数列表。

构造函数

CProimse() : m_state(CProimseState::PENDING) {}
  • 作用:初始化 Promise 的状态为 PENDING。

resolve 方法

void resolve(Element element) {
    m_element = element;
    if (m_state == CProimseState::PENDING) {
        m_state = CProimseState::FULFILLED;
        for (Resolve res : m_resolves) {
            res(element);
        }
    }
}
  • 作用:将 Promise 的状态设置为 FULFILLED,并执行所有注册的成功回调函数。

reject 方法

void reject(const std::string& reason) {
    m_reason = reason;
    if (m_state == CProimseState::PENDING) {
        m_state = CProimseState::REJECTED;
        for (Reject rej : m_rejects) {
            rej(reason);
        }
    }
}
  • 作用:将 Promise 的状态设置为 REJECTED,并执行所有注册的失败回调函数。

then 方法

CProimse* then(const Resolve& res) {
    if (m_state == CProimseState::FULFILLED) {
        res(m_element);
    } else if (m_state == CProimseState::PENDING) {
        m_resolves.push_back(res);
    }
    return this;
}
  • 作用:注册一个成功回调函数。如果 Promise 已经完成,则立即执行回调;否则,将回调添加到成功回调列表中。

onCatch 方法

void onCatch(const Reject& rej) {
    if (m_state == CProimseState::REJECTED) {
        rej(m_reason);
    } else if (m_state == CProimseState::PENDING) {
        m_rejects.push_back(rej);
    }
}
  • 作用:注册一个失败回调函数。如果 Promise 已经被拒绝,则立即执行回调;否则,将回调添加到失败回调列表中。

链式调用

通过 then 和 onCatch 方法,可以实现链式调用,使得异步操作的处理更加简洁和直观。

proimse->then([](int ele) -> void {
    std::cout << ele << std::endl;
})->onCatch([](const std::string& reason) -> void {
    std::cout << reason << std::endl;
});

使用示例

CProimse<int>* proimse = new CProimse<int>();
proimse->then([](int ele) -> void {
    std::cout << ele << std::endl;
})->onCatch([](const std::string& reason) -> void {
    std::cout << reason << std::endl;
});
proimse->reject("网络异常!!!");

std::promise 与 CProimse 对比

1. 基础功能对比

功能CProimse 实现std::promise
状态管理手动实现标准库实现
回调注册与执行手动实现标准库实现
异步支持需结合线程内置支持
链式调用支持不支持

2. 实现细节对比

(1) 状态管理
  • CProimse:通过自定义枚举 CProimseState 管理状态。
  • std::promise:状态管理由标准库实现,用户无需关注底层细节。
(2) 回调注册与执行
  • CProimse:手动维护回调队列,通过 then 和 onCatch 方法注册回调。
  • std::promise:通过 std::future 与 std::promise 配合,回调通过 future 的 get 方法触发。
(3) 异步支持
  • CProimse:需要结合 std::thread 或其他异步框架实现异步操作。
  • std::promise:内置支持异步操作,通常与 std::async 或 std::thread 结合使用。
(4) 链式调用
  • CProimse:支持链式调用,通过返回 this 实现。
  • std::promise:不支持链式调用,无法直接链式注册回调。

3. 代码示例对比

(1) CProimse 示例
CProimse<int>* proimse = new CProimse<int>();
proimse->then([](int ele) -> void {
    std::cout << ele << std::endl;
})->onCatch([](const std::string& reason) -> void {
    std::cout << reason << std::endl;
});
proimse->reject("网络异常!!!");
(2) std::promise 示例
#include <future>
#include <thread>
#include <iostream>

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    // 异步操作
    std::thread([&prom]() {
        // 模拟网络请求
        std::this_thread::sleep_for(std::chrono::seconds(1));
        prom.set_value(42);
    }).detach();
    // 注册回调
    fut.then([](std::future<int> fut) {
        try {
            int result = fut.get();
            std::cout << "结果:" << result << std::endl;
        } catch (const std::exception& e) {
            std::cout << "错误:" << e.what() << std::endl;
        }
    });
    // 主线程阻塞等待
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 0;
}

4. 优缺点分析

(1) CProimse
  • 优点:
    • 代码简洁,易于理解。
    • 支持链式调用,使用方式类似前端 Promise。
    • 可以作为学习 Promise 实现原理的示例。
  • 缺点:
    • 不支持内置异步操作,需要结合线程实现。
    • 功能较为基础,缺乏 std::promise 的高级特性(如 then 的链式返回)。
(2) std::promise
  • 优点:
    • 内置异步支持,与 std::future 配合使用,功能强大。
    • 标准库实现,性能优化和稳定性有保障。
    • 支持 C++11 及以上标准,兼容性好。
  • 缺点:
    • 使用方式较为复杂,缺乏链式调用的支持。
    • 回调机制不够灵活,无法像前端 Promise 那样优雅地处理异步流程。

总结与展望

通过手写 CProimse,我们可以深入理解 Promise 的实现原理,包括状态管理、回调注册与执行等核心机制。然而,在实际开发中,std::promise 仍然是更好的选择,因为它提供了更强大的功能和更好的性能保障。

对于开发者来说,理解 std::promise 的工作原理以及其与手写实现的异同点,有助于更好地选择合适的工具来处理异步操作。同时,手写实现虽然功能有限,但作为学习和探索的工具,仍然具有重要的价值。

希望本文能够帮助读者更好地理解 Promise 的实现原理,并在实际开发中做出更明智的选择。

目录

  1. 引言
  2. 前端 Promise 的应用与优势
  3. 常见应用场景
  4. 并发请求
  5. Promise 解决的问题
  6. 手写 C++ Promise 实现
  7. 类结构与成员变量
  8. 构造函数
  9. resolve 方法
  10. reject 方法
  11. then 方法
  12. onCatch 方法
  13. 链式调用
  14. 使用示例
  15. std::promise 与 CProimse 对比
  16. 1. 基础功能对比
  17. 2. 实现细节对比
  18. (1) 状态管理
  19. (2) 回调注册与执行
  20. (3) 异步支持
  21. (4) 链式调用
  22. 3. 代码示例对比
  23. (1) CProimse 示例
  24. (2) std::promise 示例
  25. 4. 优缺点分析
  26. (1) CProimse
  27. (2) std::promise
  28. 总结与展望
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Apache Apollo 从 Windows 迁移至 Linux 服务器全流程及避坑指南
  • Java 核心工具类实战:String 与日期时间 API
  • WebToEpub 浏览器扩展实现网页转 EPUB 电子书
  • 全国计算机等级考试二级 Python 历年真题及参考答案(综合应用题)
  • 无人机视觉目标检测数据集 VisDrone 详解
  • 渐进式 AIGC 系统架构与功能特性:支持多模态大模型与 Agent 智能体
  • C++ 核心概念:引用、内联与 nullptr 解析
  • 中小团队低成本搭建项目管理系统:Ubuntu 下 DooTask 私有化部署实战
  • OpenCode + GitHub Copilot:打造类 Claude Code 的本地编程体验
  • 归并排序与数组逆序对详解
  • Spring Data Redis Hash 结构操作指南
  • Llama-3.2V-11B-COT 部署教程:NVIDIA A10/A100/V100 多卡 GPU 适配
  • 富文本编辑集成指南:5 阶段实现低代码高效开发
  • OpenClaw 移动端部署实战:iOS/Android 离线语音 AI 助手
  • AIGC 产品经理核心能力与面试考点解析
  • OpenClaw 对接飞书机器人:消息无响应与 Gateway 断开排查
  • 前端 OFD 文件解析与渲染:基于 ofd.js 的技术实践
  • WuliArt Qwen-Image Turbo 本地部署实战指南
  • 基于 Amazon SageMaker 的 AIGC 模型训练与 Web 应用部署实践
  • GESP 2023 年 12 月 C++ 二级认证试题解析(选择题 9-15)

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online