如何在循环中调用WriteBytesAsync?自定义htmlViews编译错误排查
解决接受XmlNode列表的Giraffe htmlView变体编译错误
错误原因
原代码用mutable变量配合task表达式的for循环处理异步操作时,let! newCtx = x.WriteBytesAsync bytes后的赋值操作返回unit,不符合F# task builder的Bind方法对延续函数返回类型的要求(需返回与整个task兼容的异步结果类型),导致编译报错。
修正后的代码
let htmlViews (htmlNodes : XmlNode list) (_ : HttpFunc) (ctx: HttpContext) : HttpFuncResult = task { let bytesList = List.map RenderView.AsBytes.htmlDocument htmlNodes ctx.SetContentType "text/html; charset=utf-8" // 异步折叠累积HttpContext状态 return! bytesList |> List.fold (fun asyncCtx bytes -> task { let! currentCtxOpt = asyncCtx match currentCtxOpt with | Some currentCtx -> return! currentCtx.WriteBytesAsync bytes | None -> return None } ) (task { return Some ctx }) }
代码说明
- 用
List.fold遍历所有HTML节点的字节数据,异步累积HttpContext状态:- 初始状态为包含原始
ctx的Some值,包装在task中 - 每一步检查当前HttpContext是否存在:若存在则执行
WriteBytesAsync写入数据,返回新的HttpContext option;若不存在直接返回None
- 初始状态为包含原始
- 通过
return!返回折叠后的异步结果,完全匹配HttpFuncResult(即Task<HttpContext option>)的类型要求
内容的提问来源于stack exchange,提问作者Jeffrey Rennie
相关产品推荐
相关产品推荐

