如何使用异步转换函数来收集?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (14)

假设我有两个async职能:

  • fetchCategories获取产品类别列表(string List)
  • fetchProductsForCategory获取给定类别的产品列表(string List)

我想写一个函数fetchProducts为所有类别的产品获取所有产品。结果应该是一个元组列表(string * string List)

但是,我现在不确定是否适合asyncSeq.collect在一起。

以下是我的尝试,希望能清楚地说明这一意图:

let fetchProducts () = async {
  let! categories = fetchCategories ()
  return categories
    |> Seq.collect (fun c -> async {
      let! products = fetchProductsForCategory c
      return products
        |> Seq.map fun p -> (c, p)
    })
    |> Seq.toList
}
提问于
用户回答回答于

实现你所追求的目标最简单的方法就是运行所有fetchProductsForCategory接连,一个接一个,然后连在一起。为了在运行下一次执行之前等待上一次执行完成,请使用Async.RunSynchronously:

let fetchProducts () = async {
  let! categories = fetchCategories ()
  return categories
    |> Seq.collect (fun c ->
      fetchProductsForCategory c 
        |> Async.RunSynchronously          
        |> Seq.map (fun p -> (c, p))
    )
    |> Seq.toList
}

(顺便说一句,你的代码不会产生Seq<string * string list>,你说你希望,但是Seq<string * string>-每一种产品都有其分类,但这不是重点)

然而,这种方法明显的缺点是浪费宝贵的时间。处决fetchProductsForCategory可以并行运行,从而获得更好的性能。

Async.Parallel函数接受一系列异步计算,并行运行它们,并以数组的形式返回它们的结果:

let fetchProducts () = async {
  let! categories = fetchCategories ()
  let! products = categories 
                   |> Seq.map fetchProductsForCategory 
                   |> Async.Parallel

  Seq.zip categories products
}

所属标签

可能回答问题的人

  • 西风

    renzha.net · 站长 (已认证)

    7 粉丝1 提问9 回答
  • 四无君

    0 粉丝0 提问3 回答
  • o o

    3 粉丝490 提问2 回答
  • Dingda

    Dingda · 站长 (已认证)

    4 粉丝0 提问2 回答

扫码关注云+社区

领取腾讯云代金券