基于purescript-pipes实现带超时的await函数的技术咨询
带超时的Pipe await实现方案
你的问题核心在于:当前代码里的P.take 1 -> toOutput chan会无条件阻塞等待上游输入,即便超时逻辑已经触发,这个隐藏在toOutput里的await还是会继续等待,导致超时后必须等到下一个输入才会返回。在pipes模型下完全可以实现带超时的await功能,只需要把「等待上游值」和「超时」的逻辑直接放到同一个竞争分支里,而不是分开处理。
修正后的实现代码
import Pipes (Pipe, await) import Pipes.Aff (liftAff) import Effect.Aff (delay, oneOf, parallel, sequential, Milliseconds) import Data.Maybe (Maybe(..)) timeoutAwait :: forall a b. Milliseconds -> Pipe a b Aff (Maybe a) timeoutAwait t = liftAff $ sequential $ oneOf [ parallel $ Nothing <$ delay t , parallel $ Just <$> await ]
逻辑说明
- 直接用
oneOf把两个并行任务放在一起竞争:- 第一个分支:延迟
t毫秒后返回Nothing(超时逻辑) - 第二个分支:调用
await等待上游输入,拿到值后返回Just a
- 第一个分支:延迟
sequential会等待第一个完成的分支结果并直接返回,另一个未完成的分支会被自动取消,不会继续执行。- 这种写法避免了原代码中“超时后仍等待上游输入”的问题,因为超时触发时,
await的分支会被立即取消,不会继续阻塞。
原代码问题分析
原代码中,你先启动了超时和接收chan的竞争逻辑,随后又单独执行P.take 1 -> toOutput chan——这一步本质是调用await把上游值发送到chan,但这个await是独立于超时逻辑的,所以即便超时已经触发,这个await还是会继续等待上游输入,直到拿到值才会结束,这就是超时后仍要等下一个输入才返回的原因。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

