基于C++11手撸前端Promise

基于C++11手撸前端Promise

文章导航

引言

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

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


前端Promise的应用与优势

常见应用场景

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

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

Promise 解决的问题

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

手写 C++ Promise 实现

类结构与成员变量

template<typenameElement>classCProimse{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();voidreject(const std::string& reason);voidresolve(Element element);voidonCatch(const Reject& rej); CProimse*then(const Resolve& res);};
  • ResolveReject :定义了成功和失败回调函数的类型。
  • m_elementm_reason :分别存储 Promise 的结果和拒绝原因。
  • m_state :表示 Promise 的当前状态,初始状态为 PENDING。
  • m_resolvesm_rejects :存储注册的成功和失败回调函数列表。

构造函数

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

resolve 方法

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

reject 方法

voidreject(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);}elseif(m_state == CProimseState::PENDING){ m_resolves.push_back(res);}returnthis;}
  • 作用:注册一个成功回调函数。如果 Promise 已经完成,则立即执行回调;否则,将回调添加到成功回调列表中。

onCatch 方法

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

链式调用

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

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::promiseCProimse 对比

1. 基础功能对比

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

2. 实现细节对比

(1) 状态管理

  • CProimse :通过自定义枚举 CProimseState 管理状态。
  • std::promise :状态管理由标准库实现,用户无需关注底层细节。

(2) 回调注册与执行

  • CProimse :手动维护回调队列,通过 thenonCatch 方法注册回调。
  • std::promise :通过 std::futurestd::promise 配合,回调通过 futureget 方法触发。

(3) 异步支持

  • CProimse :需要结合 std::thread 或其他异步框架实现异步操作。
  • std::promise :内置支持异步操作,通常与 std::asyncstd::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>intmain(){ 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));return0;}

4. 优缺点分析

(1) CProimse

  • 优点
    • 代码简洁,易于理解。
    • 支持链式调用,使用方式类似前端 Promise。
    • 可以作为学习 Promise 实现原理的示例。
  • 缺点
    • 不支持内置异步操作,需要结合线程实现。
    • 功能较为基础,缺乏 std::promise 的高级特性(如 then 的链式返回)。

(2) std::promise

  • 优点
    • 内置异步支持,与 std::future 配合使用,功能强大。
    • 标准库实现,性能优化和稳定性有保障。
    • 支持 C++11 及以上标准,兼容性好。
  • 缺点
    • 使用方式较为复杂,缺乏链式调用的支持。
    • 回调机制不够灵活,无法像前端 Promise 那样优雅地处理异步流程。

总结与展望

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

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

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

Read more

AIGC(生成式AI)试用 45 -- DocsGPT 与 Python开发 1

一切从python调用本地DocsGPT完成python开发开始。 遗留问题:如何验证AI开发提交的结果? * 提问 1: 使用python+Tkinter进行GUI程序编码 1. 界面分为左右两部分     - 左侧为python代码编辑区:       左上部为代码多行输入框,嵌入python idle,浅灰色底色;       左下部为 Run 按钮     - 右侧为GPT调用区:       右上部为tab,名称 Question,嵌入多行文本,输入提问问题;       中部为Show Answer按钮,海蓝色;       下部为2个tab:tab1,名称 Answer,嵌入多行文本,显示GPT处理结果;                                tab2,名称History,显示提问历史,answer + question,数据来自名为pyai的sqlite的数据库  2. 优化界面  3. 优化代码 * DeepSeek 回复 1: - 1 次调用界面

MBA必看!10个高效降AIGC工具推荐

MBA必看!10个高效降AIGC工具推荐

MBA必看!10个高效降AIGC工具推荐 AI降重工具:MBA论文的智能护航 在当前学术写作日益依赖人工智能的背景下,MBA学生面临的挑战愈发明显。论文中高AIGC率不仅可能影响成绩,还可能导致学术不端的质疑。因此,如何高效降低AIGC率、去除AI痕迹,并有效降低查重率,成为许多MBA学习者关注的核心问题。 幸运的是,随着技术的发展,市面上涌现出众多AI降重工具,它们不仅能精准识别并优化AI生成内容,还能在保持语义通顺的前提下,实现高质量的降重效果。这些工具各具特色,有的专注于快速处理初稿,有的则擅长深度查重与修改,为不同阶段的论文写作提供了多样化的解决方案。 工具名称主要功能适用场景千笔强力去除AI痕迹、保语义降重AI率过高急需降重云笔AI多模式降重初稿快速处理锐智 AI综合查重与降重定稿前自查文途AI操作简单片段修改降重鸟同义词替换小幅度修改笔杆在线写作辅助辅助润色维普官方查重最终检测万方数据库查重数据对比Turnitin国际通用检测留学生降重ChatGPT辅助润色指令手动辅助 千笔AI(官网直达入口) :https://www.qianbixiezuo.com

【GitHub项目推荐--TypeTale(字字动画):免费AIGC视频创作工具】非开源

简介 TypeTale (字字动画)是一款专为内容创作者打造的完全免费的AIGC创作软件,主要用于小说推文、AI短剧、AI电影制作。它集成了多种AI能力,提供从文案处理到视频生成的全链路创作支持,承诺现有功能与基础功能永久免费。 🔗 GitHub地址 : https://github.com/TypeTale/TypeTale 🎬 核心价值 : AIGC视频生成 · 小说推文 · AI短剧 · 完全免费 · 中文优化 项目背景 : * 内容创作 :短视频内容创作需求增长 * AIGC技术 :AI生成内容技术成熟 * 成本控制 :降低视频制作成本需求 * 中文优化 :中文内容创作工具需求 * 开源生态 :开源创作工具生态 项目特色 : * 🆓 完全免费 :永久免费使用 * 🇨🇳 中文优化 :专为中文优化 * 🤖 AI集成 :多AI能力集成 * 🎬 视频生成 :全链路视频生成 * 🔧 易用性 :简单易用界面 技术亮点 : * 多模型支持 :支持多种AI模型 * ComfyUI集成 :深度ComfyUI集成 * 工作流系统

论文查重 AIGC 率高达 88.3%?paperxie 让你从 “学术红码” 到 “顺利通关”

论文查重 AIGC 率高达 88.3%?paperxie 让你从 “学术红码” 到 “顺利通关”

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/aippthttps://www.paperxie.cn/weight?type=1https://www.paperxie.cn/weight?type=1 在 AI 写作工具普及的今天,不少同学都遇到过这样的困境:用 AI 生成的论文初稿,AIGC 率检测直接飙到 80%+,被导师打回重写;或者明明是自己原创的内容,却因为 AI 辅助润色被判定为 “AI 生成”,面临学术不端的风险。 面对知网、维普等平台日益严格的 AIGC 检测,以及 Turnitin 对留学生论文的严苛审核,如何有效降低 AIGC 率,同时保证论文的学术性和原创性,成了当代学子的 “头等大事”。今天,