8人参与 • 2025-10-23 • C/C++
在前端开发中,promise 是处理异步操作的重要工具。它通过将异步操作封装在 promise 实例中,解决了传统回调地狱的问题,提高了代码的可读性和可维护性。promise 的概念并非前端独有,在 c++11 标准中也引入了 std::promise,用于实现类似的功能。
本文将从一个手写的 c++ promise 实现(基于 c++11)出发,分析其工作原理,并与 std::promise 进行对比,探讨两者的异同点以及适用场景。
网络请求
promise 可以用于处理 ajax 请求,简化异步数据获取的逻辑。
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log('获取到数据:', data);
})
.catch(error => {
console.error('请求失败:', error);
});
定时器
promise 还可以用于处理定时器,使代码更加直观。
function timeout(ms) {
return new promise((resolve) => {
settimeout(resolve, ms);
});
}
timeout(1000)
.then(() => {
console.log('1秒后执行');
});使用 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);
});catch 方法可以集中处理所有异步操作中的错误【1†source】。promise.all 和 promise.race,可以方便地控制多个异步操作的执行顺序和结果【5†source】。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)
{
}
void resolve(element element)
{
m_element = element;
if (m_state == cproimsestate::pending)
{
m_state = cproimsestate::fulfilled;
for (resolve res : m_resolves)
{
res(element);
}
}
}
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);
}
}
}
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;
}
void oncatch(const reject& rej)
{
if (m_state == cproimsestate::rejected)
{
rej(m_reason);
}
else if (m_state == cproimsestate::pending)
{
m_rejects.push_back(rej);
}
}
通过 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("网络异常!!!");| 功能 | cproimse 实现 | std::promise |
|---|---|---|
| 状态管理 | 手动实现 | 标准库实现 |
| 回调注册与执行 | 手动实现 | 标准库实现 |
| 异步支持 | 需结合线程 | 内置支持 |
| 链式调用 | 支持 | 不支持 |
cproimse :通过自定义枚举 cproimsestate 管理状态。std::promise :状态管理由标准库实现,用户无需关注底层细节。cproimse :手动维护回调队列,通过 then 和 oncatch 方法注册回调。std::promise :通过 std::future 与 std::promise 配合,回调通过 future 的 get 方法触发。cproimse :需要结合 std::thread 或其他异步框架实现异步操作。std::promise :内置支持异步操作,通常与 std::async 或 std::thread 结合使用。cproimse :支持链式调用,通过返回 this 实现。std::promise :不支持链式调用,无法直接链式注册回调。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("网络异常!!!");#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;
}std::promise 的高级特性(如 then 的链式返回)。std::future 配合使用,功能强大。通过手写 cproimse,我们可以深入理解 promise 的实现原理,包括状态管理、回调注册与执行等核心机制。然而,在实际开发中,std::promise 仍然是更好的选择,因为它提供了更强大的功能和更好的性能保障。
对于开发者来说,理解 std::promise 的工作原理以及其与手写实现的异同点,有助于更好地选择合适的工具来处理异步操作。同时,手写实现虽然功能有限,但作为学习和探索的工具,仍然具有重要的价值。
希望本文能够帮助读者更好地理解 promise 的实现原理,并在实际开发中做出更明智的选择。
到此这篇关于基于c++11手撸前端promise及应用与优势的文章就介绍到这了,更多相关c++ promise内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论