簡體   English   中英

用理解來構建期貨

[英]Composing Futures with For Comprehension

我有一個使用ReactiveMongo和MongoDB的Play Framework應用程序,我有以下代碼:

def categories(id: String): Future[Vector[Category]] = {...}
....
val categoriesFuture = categories(id)
for {
  categories: Vector[Category] <- categoriesFuture
  categoryIdsWithoutPerson: Vector[BSONObjectID] <- findCategoryIdsWithoutPerson(categories.map(_.id), personId) //Returns Future[Vector[BSONObjectID]]
  categoriesWithoutPerson: Vector[Category] <- categories.filter(category => categoryIdsWithoutPerson.contains(category.id)) //Play cites the error here
} yield categoryIdsWithoutPerson

為了解釋這段代碼,我獲取了一個包含在FutureCategories Vector ,因為這就是ReactiveMongo的滾動方式。 for comprehension中,我使用該Vector然后從數據庫中獲取id列表。 最后,我使用filter調用來僅保留那些id可以在id列表中找到的類別。

這一切看起來都相當簡單。 問題是Play在for comprehension的最后一行給出了以下編譯錯誤:

pattern type is incompatible with expected type;
 found   : Vector[com.myapp.Category]
 required: com.myapp.Category

我不確定為什么所需的類型是Category的單個實例。

我可以使用一些洞察我做錯了什么和/或是否有更簡單或更慣用的方法來實現這一點。

看起來你正試圖用Vector組合Futures 因為scala中的理解必須具有相同的更高類型,在您的情況下是Future 當您展開for comprehension的'sugar'時,它只是在所有內容上調用flatMap

for {
  categories <- categoriesFuture
  // I'm not sure what the return type is here, but I'm guessing it's a future as well
  categoryIdsWithoutPerson <- findCategoryIdsWithoutPerson(categories.map(_.id), personId)
  // Here we use = to get around need to flatMap
  categoriesWithoutPerson = categories.filter(category => categoryIdsWithoutPerson.contains(category.id))
} yield categoryIdsWithoutPerson

你的代碼消失了:

categoriesFuture.flatMap(categories => 
  findCategoryIdsWithoutPerson(categories.map(_.id), personId).
    flatMap(categoryIdsWithoutPerson => 
       categories.filter(category => categoryIdsWithoutPerson.contains(category.id)).
          map(_ => categoryIdsWithoutPerson))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM