वादा और भविष्य पूरक अवधारणाएँ हैं। फ्यूचर एक ऐसा मूल्य है जिसे भविष्य में कभी भी प्राप्त किया जा सकता है। इसलिए, यह एक संगणना के पढ़ने या बाहर समापन बिंदु है - यह कुछ ऐसा है जिसे आप से एक मान प्राप्त करते हैं।
एक वादा, सादृश्य द्वारा, अभिकलन के लेखन पक्ष है। आप एक वादा बनाते हैं जो वह जगह है जहां आप गणना का परिणाम डालेंगे और उस वादे से आपको एक भविष्य मिलेगा जिसका उपयोग उस परिणाम को पढ़ने के लिए किया जाएगा जिसे वादे में डाल दिया गया था। जब आप एक वादा पूरा करेंगे, तो असफलता या सफलता से, आप उन सभी व्यवहारों को ट्रिगर करेंगे जो संबद्ध भविष्य से जुड़े थे।
आपके पहले प्रश्न के बारे में, यह कैसे हो सकता है कि एक वादा पी के लिए हमारे पास है p.future == p
। आप इसे एकल-आइटम बफर की तरह कल्पना कर सकते हैं - एक कंटेनर जो शुरू में खाली है और आप बाद में एक मूल्य को संग्रहीत कर सकते हैं जो हमेशा के लिए इसकी सामग्री बन जाएगा। अब, आपके दृष्टिकोण के आधार पर यह एक वादा और भविष्य दोनों है। यह किसी ऐसे व्यक्ति के लिए वादा है जो बफर में मूल्य लिखने का इरादा रखता है। यह उस व्यक्ति के लिए एक भविष्य है जो उस मूल्य का इंतजार करता है जिसे बफर में रखा जाए।
विशेष रूप से, स्काला समवर्ती एपीआई के लिए, यदि आप यहां प्रॉमिस विशेषता पर एक नज़र डालते हैं, तो आप देख सकते हैं कि प्रोमिस साथी ऑब्जेक्ट से कैसे तरीके लागू होते हैं:
object Promise {
/** Creates a promise object which can be completed with a value.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
def apply[T](): Promise[T] = new impl.Promise.DefaultPromise[T]()
/** Creates an already completed Promise with the specified exception.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
def failed[T](exception: Throwable): Promise[T] = new impl.Promise.KeptPromise[T](Failure(exception))
/** Creates an already completed Promise with the specified result.
*
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
def successful[T](result: T): Promise[T] = new impl.Promise.KeptPromise[T](Success(result))
}
अब, वादों के कार्यान्वयन, DefaultPromise और KeptPromise यहाँ पाए जा सकते हैं । वे दोनों एक आधार थोड़ा विशेषता का विस्तार करते हैं जिसका नाम समान होता है, लेकिन यह एक अलग पैकेज में स्थित होता है:
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
def future: this.type = this
}
तो आप देख सकते हैं कि उनका क्या मतलब है p.future == p
।
DefaultPromise
वह बफर है जिसका मैं ऊपर उल्लेख कर रहा था, जबकि KeptPromise
एक बफर है जिसके मूल्य में बहुत सृजन है।
आपके उदाहरण के बारे में, आपके द्वारा उपयोग किए जाने वाले भविष्य के ब्लॉक वास्तव में पर्दे के पीछे एक वादा करता है। की परिभाषा को आइए नज़र future
में यहाँ :
def future[T](body: =>T)(implicit execctx: ExecutionContext): Future[T] = Future[T](body)
तरीकों की श्रृंखला का पालन करके आप में समाप्त impl.Future :
private[concurrent] object Future {
class PromiseCompletingRunnable[T](body: => T) extends Runnable {
val promise = new Promise.DefaultPromise[T]()
override def run() = {
promise complete {
try Success(body) catch { case NonFatal(e) => Failure(e) }
}
}
}
def apply[T](body: =>T)(implicit executor: ExecutionContext): scala.concurrent.Future[T] = {
val runnable = new PromiseCompletingRunnable(body)
executor.execute(runnable)
runnable.promise.future
}
}
इसलिए, जैसा कि आप देख सकते हैं, आप अपने निर्माता ब्लॉक से जो परिणाम प्राप्त करते हैं वह एक वादा में डाला जाता है।
लेदर संस्करण :
वास्तविक दुनिया के उपयोग के बारे में: अधिकांश समय आप सीधे वादों से नहीं निपटेंगे। यदि आप एक पुस्तकालय का उपयोग करेंगे जो अतुल्यकालिक गणना करता है तो आप बस पुस्तकालय के तरीकों द्वारा लौटे वायदा के साथ काम करेंगे। वादे, इस मामले में, पुस्तकालय द्वारा बनाए गए हैं - आप बस उन तरीकों के पढ़ने के अंत के साथ काम कर रहे हैं।
लेकिन अगर आपको अपने स्वयं के अतुल्यकालिक एपीआई को लागू करने की आवश्यकता है, तो आपको उनके साथ काम करना शुरू करना होगा। मान लीजिए कि आपको सबसे ऊपर एक async HTTP क्लाइंट को लागू करने की आवश्यकता है, जो कहता है, Netty। तब आपका कोड कुछ इस तरह दिखाई देगा
def makeHTTPCall(request: Request): Future[Response] = {
val p = Promise[Response]
registerOnCompleteCallback(buffer => {
val response = makeResponse(buffer)
p success response
})
p.future
}