मेरे पास स्कैला में आईडी की एक सूची है और प्रत्येक आईडी के लिए मैंने नीचे एक डेटाबेस ऑपरेशन करने के लिए भविष्य लॉन्च किया है:
import myPackage.myExecutionContext
def doDbOperation(ids: List[Long]) = ids.map { id =>
Future(get(id))
}
मैंने देखा कि फ्यूचर्स केवल बाद में निष्पादित किए जाते हैंसूची का ट्रैवर्सल पूरा हो गया है (सूची बहुत बड़ी है)। ट्रैवर्सल को पूरा करने के इंतजार किए बिना मैं भविष्य के रूप में और जब संभव हो (उपलब्ध धागे के आधार पर) कैसे लॉन्च करूं?
उत्तर:
उत्तर № 1 के लिए 4पर एक नज़र डालें Future.traverse
। डॉक्स कहते हैं, "यह समानांतर मानचित्र करने के लिए उपयोगी है। उदाहरण के लिए, समांतर में किसी सूची के सभी आइटमों पर फ़ंक्शन लागू करने के लिए"।
Future.traverse(ids)(id => Future(get(id)))
उत्तर № 2 के लिए 1
मैं मनाए गए व्यवहार की व्याख्या नहीं कर सकता (भविष्य का शरीर नक्शा ट्रैवर्सल पूरा होने तक निष्पादित नहीं कर रहा है)। निम्नलिखित प्रिंट करेंगे 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
यह अलग-अलग प्रदर्शन नहीं करता है कि इसे अंदर के अंदर बुलाया जाता है या नहीं map
या ए Future.traverse
.
पुन: Future.traverse
वापसी प्रकार अलग हैं।
ids.map { id => Future(get(id)) }
रिटर्न List[Future[DBObject]]
परंतु
Future.traverse(ids)(id => Future(get(id)))
रिटर्न Future[List[DBObject]]
Future[List[DBObject]]
लगभग हमेशा अधिक उपयोगी है लेकिन आप अर्थशास्त्र बदल रहे हैं (और शायद आप नहीं चाहते हैं)।