/ / Scala: Начертайте списък с идентификационни номера, за да стартирате бъдещето за всеки - скала, бъдеще

Скала: Начертайте списък с идентификационни номера, за да стартирате бъдещето за всеки - скала, бъдеще

Имам списък с идентификационни номера в Scala и за всеки идентификатор, който пускам бъдеще, за да извърша операция по базата данни по-долу:

import myPackage.myExecutionContext

def doDbOperation(ids: List[Long]) = ids.map { id =>
Future(get(id))
}

Забелязвам, че Фючърсите се изпълняват едва след товаПреминаването на списъка е завършено (списъкът е доста голям). Как да направя бъдещето да бъде стартирано, когато е възможно (въз основа на наличните нишки), без да се чака завършването на траверса?

Отговори:

4 за отговор № 1

Погледни Future.traverse, Документите казват: "Това е полезно за извършване на паралелна карта. Например, за да приложите функция към всички елементи от списъка паралелно".

Future.traverse(ids)(id => Future(get(id)))

1 за отговор № 2

Не мога да обясня наблюдаваното поведение (Бъдещото тяло не се изпълнява до завършването на картата). Следното ще отпечата Running future while mapping:

package org.example

import scala.concurrent.{ Future }
import scala.concurrent.ExecutionContext.Implicits.global

object Test extends App {

@volatile var hasStarted = false

val ids: List[Long] = Range.Long(0L, 100000L, 1L).toList

val res = ids.map({ id =>
val res = Future {
if (!hasStarted) hasStarted = true
id
}
if (hasStarted) println("Running future while mapping")
res
})
}

Което има смисъл; Future.apply не се изпълнява различно в зависимост от това дали се нарича вътре в a map или a Future.traverse.

Re: Future.traverse Типовете връщане са различни.

ids.map { id => Future(get(id)) } се завръща List[Future[DBObject]]

но

Future.traverse(ids)(id => Future(get(id))) се завръща Future[List[DBObject]]

Future[List[DBObject]] е почти винаги по-полезен, но променяте семантиката (и може би не искате).