您好,登錄后才能下訂單哦!
這篇文章主要講解了“Future的sequence怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Future的sequence怎么實現”吧!
1)關于Option[T], Either[E, R] 和 Try[T]的使用場景。
這三種type很容易讓人想到處理Exception的場景。這些types如果只是針對Exception就略顯狹隘了。現在我的感覺是:
1)Option適于處理業務邏輯上需要空值的地方,這里不一定是因為Exception導致。往往是業務上需要表達這種“空”/“沒值”。
2)Either的左值不一定是Exception,表示一個計算可能有兩種結果比較好,右值按照慣例表示正確/正常路徑下的結果。左值是另個分支的結果。當然,也可以放Exception,Error什么的。STTP的Response body部分就是一個Either[Error, T]。
3)Try,其實才是最適合表示一個計算可能出現Exception的type。Try的apply()接受的就是一個代碼塊并運行,對異常封裝到子類Failure。
最后的感覺是Option,Either更像標量,是結果的一個靜態表示。而Try是動態的,包含了代碼的執行。看Try的定義體會下:
object Try { def apply[T](r: => T): Try[T] = try Success(r) catch { case NonFatal(e) => Failure(e) }}
2)Future's sequence()的實現。
1)這是Erik喜歡的遞歸方式的實現。
其中兩個flatMap都是Future上的flatMap。
def sequence[T](fts: List[Future[T]]): Future[List[T]] = { fts match { case Nil => Future(Nil) case ft::fts => ft.flatMap( t => sequence(fts).flatMap(ts => Future(t::ts))) }}
2)通過類型推導,我發現把flatMap()換成了map()也符合類型檢查,似乎也也沒有大的問題。但在邏輯上,這個實現就是要要等著所有的future依次從尾部開始都complete了才能執行。而上面的實現整個過程都是異步的,更符合Future的原意。
def sequence[T](fts: List[Future[T]]): Future[List[T]] = { fts match { case Nil => Future(Nil) case ft::fts => ft.flatMap( t => sequence(fts).map(ts => t::ts)) }}
3)Erik通過async,await實現的sequence。
這種方式似乎更容易理解,但風格太不FP了。Erik警告說,如果是基于Future編程,那么不要wait。但是在async塊里除外,因為async本身是異步的所以不會阻塞。另外,async/await在模塊scala-async里,需要加到sbt的依賴里。
import scala.async.Async.{async, await}def sequence[T](fs: List[Future[T]]): Future[List[T]] = async { var _fs = fs val result = ListBuffer[T]() while (_fs != Nil) { result += await { _fs.head } _fs = _fs.tail } result.toList}
感謝各位的閱讀,以上就是“Future的sequence怎么實現”的內容了,經過本文的學習后,相信大家對Future的sequence怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。