C++中std::future无.then()需手动实现链式异步:一用packaged_task+thread显式触发promise;二用promise配对串接;三封装RetryableFuture支持重试;四用condition_variable模拟回调;五用C++20协程天然链式。

如果您尝试在C++中构建异步任务链,但发现std::future无法直接调用.then()方法,则可能是由于标准C++11/14/17未提供链式接口,且std::future不可拷贝、仅可移动并仅支持单次get()。以下是实现该模型的多种设计方案:
一、基于std::packaged_task与std::thread的手动链式封装
该方案利用std::packaged_task封装可调用对象及其关联的std::future,通过独立线程执行任务,并在完成时显式触发下游promise,避免阻塞主线程,同时保证移动语义安全和异常传播完整性。
1、定义任务节点结构体,包含std::packaged_task
2、为每个任务创建std::packaged_task实例,将上一任务结果(或初始值)以值捕获方式绑定进lambda。
立即学习“C++免费学习笔记(深入)”;
3、使用std::thread启动该packaged_task,并立即detach,确保异步执行不阻塞当前作用域。
4、在前序任务的线程函数末尾,调用下一节点std::promise::set_value(),传入计算结果;若发生异常,则调用set_exception(std::current_exception())。
5、下游future通过wait()或wait_for()监听就绪状态,再调用get()提取值,注意每个future只能调用一次get()。
二、基于std::promise显式串接的两阶异步计算模型
此方案直接操作std::promise与std::future配对关系,通过lambda值捕获已move的promise,在子线程中完成set_value(),确保共享状态句柄有效存活,适用于确定性短链场景。
1、声明第一个std::promise
2、构造第二个std::promise<:string> p2,同样获取f2 = p2.get_future()。
3、启动std::thread,捕获p1(使用std::move(p1))和p2(使用std::move(p2)),并标记mutable属性。
4、在线程函数体内调用p1.set_value(42),随后立即调用f1.get()获得结果,并传入字符串转换逻辑。
5、将转换结果通过p2.set_value(std::to_string(x))写入第二阶段future,确保p2生命周期覆盖整个线程执行期。
6、主线程中调用f2.get()获取最终字符串结果,注意:f1.get()必须在p1.set_value()之后且仅调用一次。
三、RAII式RetryableFuture封装实现带超时重试的链式节点
该方案将超时等待与重试逻辑封装为模板类RetryableFuture,利用std::async启动任务,并在wait_with_retry()中循环检测std::future_status::timeout,自动重建future,维持链式输入输出语义。
1、定义模板类RetryableFuture
2、在构造函数中调用std::async(std::launch::async, task_func, std::forward
3、实现wait_with_retry()成员函数,初始化重试计数器为0,进入while循环。
4、每次循环调用future.wait_for(std::chrono::milliseconds(timeout_ms)),判断返回值是否为std::future_status::timeout。
5、若超时且计数器小于max_retries,则销毁当前future,重新调用std::async生成新future,计数器加一;否则跳出循环。
6、循环结束后检查future.valid()与status,若为ready则调用get()返回T类型结果,若重试耗尽则抛出std::runtime_error("Retry limit exceeded")。
四、std::condition_variable + 共享状态标志位模拟回调式链式调度
该方案规避std::future::wait()阻塞风险,改用轻量级条件变量配合原子布尔标志位,在任务完成时通知等待方,实现非轮询、低开销的状态同步,适合资源受限环境。
1、定义共享结构体SharedState,包含std::atomic
2、前序任务执行完毕后,在临界区内设置ready.store(true),然后调用cv.notify_one()。
3、下游任务启动后,调用cv.wait(lock, [&]{ return ready.load(); }),等待ready变为true。
4、唤醒后从payload中std::any_cast提取结果,并构造新的SharedState传递给下一环节。
5、所有SharedState实例均通过std::shared_ptr管理生命周期,禁止在lambda中捕获局部SharedState对象的引用。
五、C++20协程+std::coroutine_handle构建轻量级无栈链式流水线
该方案利用co_await挂起与恢复机制,将每个异步步骤抽象为awaitable对象,通过co_spawn调度执行,天然支持异常传播与栈展开,无需手动管理promise/future配对。
1、定义awaitable包装器template
2、在promise_type中维护std::optional
3、编写协程函数auto step1(int x) -> Task
4、主协程中执行co_await step1(5); 再co_await step2(result); 形成隐式链式依赖。
5、使用asio::io_context或自定义executor运行co_spawn(ctx, main_coro(), on_done),确保on_done回调能接收co_return值与异常。


















