JavaScript में Deferred, Promise और Future के बीच क्या अंतर हैं?


300

Deferreds, वादे और वायदा के बीच अंतर क्या हैं?
क्या इन तीनों के पीछे आम तौर पर स्वीकृत सिद्धांत है?


11
मुझे नहीं लगता कि इसका jQuery से कोई
लेना

11
इसे पढ़ने के लिए: msdn.microsoft.com/en-us/scriptjunkie/gg723713
jfriend00

8
मैंने स्वयं उनका उपयोग नहीं किया है, लेकिन यहां विकिपीडिया en.wikipedia.org/wiki/Futures_and_promises पर एक बहुत अच्छा परिचय है । हालांकि मैं पूरी तरह से उपयोग के मामले को ठीक से नहीं समझता। जावास्क्रिप्ट की तरह एक async घटना संचालित भाषा में। पहली नज़र में, मैं देख नहीं सकता कि वे कॉलबैक पर क्या पेशकश करते हैं, इसके अलावा शायद एक क्लीनर एपी भी। मुझे अच्छा लगेगा अगर कोई एक उदाहरण का उपयोग करने का मामला प्रदान कर सके, और दिखा सके कि ये अवधारणाएँ कैसे लागू की जाती हैं, और कॉलबैक एक अकुशल समाधान क्यों होगा। @duri का jQuery से कोई लेना-देना नहीं है। क्या jQuery टैग को हटाया जा सकता है
AshHeskes

2
@ jfriend00 महान लिंक, शायद एक जवाब में काम किया जाना चाहिए।
fncomp

@ jfriend00 नया लिंक - msdn.microsoft.com/en-us/magazine/gg723713.aspx
c69

जवाबों:


97

ओपी के सवाल का जवाब देने का प्रयास मैंने कैसे किया, इसके लिए स्पष्ट नापसंद के प्रकाश में। शाब्दिक उत्तर है, एक वादा कुछ साझा w / अन्य वस्तुएं हैं, जबकि एक आस्थगित को निजी रखा जाना चाहिए। मुख्य रूप से, एक स्थगित (जो आमतौर पर वादा करता है) खुद को हल कर सकता है, जबकि एक वादा ऐसा करने में सक्षम नहीं हो सकता है।

यदि आप माइनुटिया में रुचि रखते हैं, तो प्रोमिस / ए + की जांच करें ।


जहाँ तक मुझे पता है, ओवररचिंग उद्देश्य एक मानकीकृत इंटरफ़ेस के माध्यम से स्पष्टता और ढीली युग्मन में सुधार करना है। @ Jfriend00 से पढ़े गए सुझाव देखें :

फ़ंक्शंस में सीधे कॉलबैक से गुजरने के बजाय, कुछ ऐसा हो सकता है जो कसकर युग्मित इंटरफेस पैदा कर सकता है, वादों का उपयोग करके किसी को कोड के लिए अलग-अलग चिंताओं को समकालिक या अतुल्यकालिक करने की अनुमति मिलती है।

निजी तौर पर, मैंने विशेष रूप से उपयोगी पाया है जब उदाहरण के लिए जो अतुल्यकालिक अनुरोधों से भरे हुए हैं, जो कि निर्भरता के नेटवर्क वाले स्क्रिप्ट लोड करने, और गैर-अवरोधक तरीके से डेटा बनाने के लिए उपयोगकर्ता प्रतिक्रिया प्रदान करते हैं।

दरअसल, JSM मोड में कोडमिरर को अतुल्यकालिक रूप से लोड करने के बाद कुछ करने के शुद्ध कॉलबैक फॉर्म की तुलना करें (माफी, मैंने थोड़ी देर में jQuery का उपयोग नहीं किया है ):

/* assume getScript has signature like: function (path, callback, context) 
   and listens to onload && onreadystatechange */
$(function () {
   getScript('path/to/CodeMirror', getJSMode);

   // onreadystate is not reliable for callback args.
   function getJSMode() {
       getScript('path/to/CodeMirror/mode/javascript/javascript.js', 
           ourAwesomeScript);
   };

   function ourAwesomeScript() {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   };
});

तैयार किए गए वादों के लिए (फिर, माफी, मैं jQuery पर तारीख तक नहीं हूँ):

/* Assume getScript returns a promise object */
$(function () {
   $.when(
       getScript('path/to/CodeMirror'),
       getScript('path/to/CodeMirror/mode/javascript/javascript.js')
   ).then(function () {
       console.log("CodeMirror is awesome, but I'm too impatient.");
   });
});

अर्ध-छद्म कोड के लिए क्षमा याचना, लेकिन मुझे आशा है कि यह मूल विचार को कुछ हद तक स्पष्ट करता है। मूल रूप से, एक मानकीकृत वादा वापस करके, आप वादा को पास कर सकते हैं, इस प्रकार अधिक स्पष्ट समूह के लिए अनुमति दे सकते हैं।


10
हालांकि यह उत्तर उपयोगी हो सकता है, यह तथ्यात्मक रूप से प्रश्न को संबोधित नहीं करता है: तथाकथित deferreds कार्यान्वयन के आधार पर वायदा या वादे हैं।
awdz9nld

@ MartinKällman तुम सही हो! मैंने कुछ समय में इस पर दोबारा गौर नहीं किया था और थोड़ा सीखा है। मैं नीचे एक अलग उत्तर पोस्ट करूंगा, लेकिन इसे छोड़ दें क्योंकि लोगों को लगता है कि उपयोग उदाहरण से लाभ हुआ है।
fncomp

@ MartinKällman ने एक नया उत्तर लिखने पर विचार किया। हालाँकि, मुझे लगता है कि ओपी वास्तव में जानना चाहता था कि प्रॉमिस और डिफ्रेड्स क्या हैं। उनके वास्तविक प्रश्न का उत्तर, मोटे तौर पर, "deferreds अपने स्वयं को हल कर सकते हैं। AFAIK, वादों और deferreds के पीछे सिद्धांत आता है [कार्यात्मक प्रतिक्रियाशील प्रोग्रामिंग | haskell.org/haskellariki/Functional_Reactive_Programming] , जो सपाट कॉलबैक के लिए एक तकनीक है। । "
fncomp

2
यह पूरी तरह से गलत है और आपके उदाहरण कॉलबैक के साथ करना आसान है। वादे कॉलबैक एकत्रीकरण और डीकोपिंग के बारे में नहीं हैं, लेकिन एसिंक्स कोड लिखने के लिए एक सिंक प्रदान करते हैं जैसे सिंक कोड लिखा जाता है। विशेष रूप fn(callback, errback)से किसी भी अधिक कसकर युग्मित या उससे कम उपयोगी नहीं है fn().then(callback, errback)- लेकिन यह वैसे भी वादों का उपयोग करने का एक गलत तरीका है। मैं विशेष रूप से कार्गो पंथ के $.whenउदाहरण से नफरत करता हूं - कोई कारण नहीं है कि आपके पास $.whenकॉलबैक के साथ काम करने वाला फ़ंक्शन नहीं हो सकता है ।
एसेलीजा

यह प्रश्न का उत्तर नहीं देता है, हालांकि +1 कि मैं यह जानने में सक्षम हो सकता हूं कि कॉलबैक नरक क्या है।
भोजेन्द्र रौनियार

146

चयनित जवाब सहित ये जवाब, धारणात्मक वादों को शुरू करने के लिए, लेकिन की बारीकियों में कमी वास्तव में क्या मतभेद शब्दावली है कि जब उन्हें लागू करने (और वहाँ लाइब्रेरी का उपयोग कर उठता में हैं के लिए अच्छे हैं कर रहे हैं महत्वपूर्ण अंतर)।

चूंकि यह अभी भी एक उभरती हुई कल्पना है , इसका उत्तर वर्तमान में दोनों संदर्भों (जैसे विकिपीडिया ) और कार्यान्वयन (जैसे jQuery ) का सर्वेक्षण करने के प्रयास से आता है :

  • आस्थगित : कभी भी लोकप्रिय संदर्भों में वर्णित नहीं, 1 2 3 4 लेकिन आमतौर पर वादे के संकल्प (कार्यान्वयन और ) के मध्यस्थ के रूप में कार्यान्वयन द्वारा उपयोग किया जाता है । 7 resolvereject

    कभी-कभी आस्थगित भी वादे (लागू करने then) होते हैं, 5 6 अन्य बार इसे अधिक शुद्ध के रूप में देखा जाता है, केवल संकल्प के लिए सक्षम होने के लिए, और उपयोगकर्ता को उपयोग करने के लिए वादा करने के लिए मजबूर किया जाता है । 7 then

  • वादा : चर्चा के तहत रणनीति के लिए सबसे अधिक व्यापक शब्द।

    एक प्रॉक्सी ऑब्जेक्ट एक लक्ष्य फ़ंक्शन के परिणाम को संग्रहीत करता है जिसकी समकालिकता हम सार करना चाहते हैं, साथ ही एक thenफ़ंक्शन को दूसरे लक्ष्य फ़ंक्शन को स्वीकार करने और एक नया वादा वापस करने के लिए उजागर करेंगे । 2

    CommonJS से उदाहरण :

    > asyncComputeTheAnswerToEverything()
        .then(addTwo)
        .then(printResult);
    44

     

    हमेशा लोकप्रिय संदर्भों में वर्णित किया गया है, हालांकि यह निर्दिष्ट नहीं किया जाता है कि किसका उत्तरदायित्व संकल्प पर पड़ता है। 1 2 3 4

    हमेशा लोकप्रिय क्रियान्वयन में मौजूद रहे, और कभी संकल्प abilites नहीं दिया। 7

  • भविष्य : कुछ लोकप्रिय संदर्भों में पाया जाने वाला पदावनत पदावनत शब्द 1 और कम से कम एक लोकप्रिय कार्यान्वयन, 8 लेकिन प्रतीत होता है कि शब्द 'वादे' 3 के लिए वरीयता में चर्चा से बाहर रखा गया है और हमेशा विषय के लिए लोकप्रिय परिचय में उल्लेख नहीं किया गया है। 9

    हालाँकि, कम से कम एक लाइब्रेरी उदारता से अमूर्तता और त्रुटि से निपटने के लिए शब्द का उपयोग करता है, जबकि thenकार्यक्षमता प्रदान नहीं करता है। 10 यह स्पष्ट नहीं है कि 'वादा' शब्द से परहेज जानबूझकर किया गया था, लेकिन संभवतः एक अच्छा विकल्प है क्योंकि वादे 'तबेले' के आसपास बनाए जाते हैं। 2

संदर्भ

  1. वादा और वायदा पर विकिपीडिया
  2. वादा / ए + कल्पना
  3. प्रॉमिस पर डोम स्टैंडर्ड
  4. DOM स्टैंडर्ड प्रॉमिस स्पेक WIP
  5. DOJO टूलकिट Deferreds
  6. jQuery के डिफ्रेड्स
  7. क्यू
  8. FutureJS
  9. वादा पर कार्यात्मक जावास्क्रिप्ट अनुभाग
  10. AngularJS एकीकरण परीक्षण में वायदा

संभावित रूप से भ्रमित करने वाली चीजें


5
"भविष्य" शब्द पर थोड़ा और स्पष्टीकरण जोड़ने के लिए - वायदा का 80 के दशक के मध्य तक कई प्रोग्रामिंग भाषाओं में एक लंबा इतिहास रहा है। और यह शब्द आज भी व्यापक उपयोग में है, विशेष रूप से जेवीएम पर। लगता है कि जावास्क्रिप्ट का उपयोग "वादा" शब्द का उपयोग करने के लिए किया गया है, जिसका अर्थ है कि जावा का अर्थ "भविष्य" के समान है। स्काला उसी अवधारणा को "फ्यूचर" और "प्रॉमिस" में "रीड" हैंडल को संदर्भित करने के लिए अलग करता है और जावास्क्रिप्ट प्रोग्रामर प्रॉमिस को "राइट" हैंडल कहते हैं।
हीदर मिलर

1
और निश्चित रूप से Microsoft को इसके लिए अपने स्वयं के कार्यकाल के साथ आना था, इसलिए C # में उन्हें कहा जाता हैTask
BlueRaja - Danny Pflughoeft

72

क्या वास्तव में यह सब मेरे लिए क्लिक किया था यह Domenic Denicola की प्रस्तुति थी।

एक गीथुब जिस्ट में , उन्होंने मुझे सबसे अधिक पसंद किया, यह बहुत संक्षिप्त है:

वादों की बात यह है कि हमें async दुनिया में कार्यात्मक संरचना और त्रुटि को पीछे छोड़ना है।

दूसरे शब्दों में, वादे एक ऐसा तरीका है जो हमें अतुल्यकालिक कोड लिखने की अनुमति देता है जो लगभग लिखना उतना ही आसान है जितना कि यह तुल्यकालिक था ।

वादों के साथ इस उदाहरण पर विचार करें:

getTweetsFor("domenic") // promise-returning async function
    .then(function (tweets) {
        var shortUrls = parseTweetsForUrls(tweets);
        var mostRecentShortUrl = shortUrls[0];
        return expandUrlUsingTwitterApi(mostRecentShortUrl); // promise-returning async function
    })
    .then(doHttpRequest) // promise-returning async function
    .then(
        function (responseBody) {
            console.log("Most recent link text:", responseBody);
        },
        function (error) {
            console.error("Error with the twitterverse:", error);
        }
    );

यह काम करता है जैसे कि आप इस तुल्यकालिक कोड को लिख रहे थे:

try {
    var tweets = getTweetsFor("domenic"); // blocking
    var shortUrls = parseTweetsForUrls(tweets);
    var mostRecentShortUrl = shortUrls[0];
    var responseBody = doHttpRequest(expandUrlUsingTwitterApi(mostRecentShortUrl)); // blocking x 2
    console.log("Most recent link text:", responseBody);
} catch (error) {
    console.error("Error with the twitterverse: ", error);
}

(यदि यह अभी भी जटिल लगता है, तो उस प्रस्तुति को देखें!)

आस्थगित के बारे में, यह एक तरीका है .resolve()या .reject()वादों का। में वादे / बी कल्पना है, यह कहा जाता है .defer()। JQuery में, यह है $.Deferred()

कृपया ध्यान दें कि जहां तक ​​मुझे पता है, jQuery में वादा कार्यान्वयन टूट गया है (देखें कि अच्छा है), कम से कम jQuery के 1.8.2 के रूप में।
यह कथित तौर पर वादा करता है / एक तबेला लागू करता है , लेकिन आपको सही त्रुटि से निपटने की ज़रूरत नहीं है, इस अर्थ में कि पूरे "async कोशिश / पकड़" कार्यक्षमता काम नहीं करेगी। जो एक दया है, क्योंकि async कोड के साथ "कोशिश / पकड़" पूरी तरह से शांत है।

यदि आप वादों का उपयोग करने जा रहे हैं (आपको अपने कोड के साथ उन्हें आज़माना चाहिए!), क्रिश कोवल के क्यू का उपयोग करें । JQuery संस्करण क्लीनर jQuery कोड लिखने के लिए सिर्फ कुछ कॉलबैक एग्रीगेटर है, लेकिन इस बिंदु को याद करता है।

भविष्य के बारे में, मेरे पास कोई विचार नहीं है, मैंने इसे किसी भी एपीआई में नहीं देखा है।

संपादित करें: Domenic Denicola की यूट्यूब पर @Farm की टिप्पणी के वादे से संबंधित है

वीडियो से माइकल जैक्सन (हाँ, माइकल जैक्सन ) का एक उद्धरण :

मैं चाहता हूं कि आप इस वाक्यांश को अपने दिमाग में जलाएं: एक वादा एक अतुल्यकालिक मूल्य है

यह एक उत्कृष्ट विवरण है: एक वादा भविष्य से एक चर की तरह है - किसी चीज के लिए प्रथम श्रेणी का संदर्भ, किसी बिंदु पर, मौजूद होगा (या होता है)।


5
W3 और क्रोम कोर टीम के एक सदस्य द्वारा फ्यूचर्स (अब डोम में कार्यान्वित!) का एक बड़ा विवरण यहां पाया जाना है: xanthir.com/b4PY0
ओलिगोफ़ेन

1
@oligofren लिंक के लिए धन्यवाद, यह अच्छा लगता है! वैसे, क्या एक रहस्यमय रूप से कष्टप्रद favicon lol।
कैमिलो मार्टिन

1
इस उत्तर को और अधिक बढ़ाने की जरूरत है। इसे स्वीकार किए गए उत्तर IMO से अधिक वोट दिया जाना चाहिए।
Chev

1
वादे पर Domenic Denicola के यूट्यूब बात: youtube.com/watch?v=hf1T_AONQJU
फार्म

@ शानदार! मैं जवाब में जोड़ दूँगा।
कैमिलो मार्टिन

32

एक वादा वादा किए जाने पर जरूरी नहीं कि मूल्य के लिए एक प्रॉक्सी का प्रतिनिधित्व करता है। यह आपको हैंडलर को एक अतुल्यकालिक कार्रवाई के अंतिम सफलता मूल्य या विफलता के कारण से जोड़ने की अनुमति देता है। यह एसिंक्रोनस विधियों को सिंक्रोनस विधियों की तरह मान लौटाता है: अंतिम मूल्य के बजाय, एसिंक्रोनस विधि भविष्य में कुछ बिंदु पर एक मूल्य होने का वादा लौटाती है।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

deferred.promise()विधि एक अतुल्यकालिक समारोह प्रगति या अपने आंतरिक अनुरोध की स्थिति में हस्तक्षेप करने से अन्य कोड को रोकने के लिए अनुमति देता है। वादा केवल अतिरिक्त हैंडलर संलग्न करने या राज्य ( तब, किया, विफल, हमेशा, पाइप, प्रगति, राज्य और वादा ) को निर्धारित करने के लिए आवश्यक स्थगित तरीकों को उजागर करता है , लेकिन वे नहीं जो राज्य को बदलते हैं ( संकल्प, अस्वीकार, अधिसूचित, हल करें) अस्वीकार (और सूचना के साथ )।

यदि लक्ष्य प्रदान किया गया है, deferred.promise()तो उस पर तरीके संलग्न करेंगे और फिर एक नया बनाने के बजाय इस ऑब्जेक्ट को वापस करेंगे। यह वादा व्यवहार को उस वस्तु से जोड़ने के लिए उपयोगी हो सकता है जो पहले से मौजूद है।

यदि आप एक आस्थगित बना रहे हैं, तो आस्थगित का एक संदर्भ रखें ताकि इसे किसी बिंदु पर हल या अस्वीकार किया जा सके। केवल प्रॉमिस ऑब्जेक्ट को deferred.promise () के माध्यम से लौटाएं ताकि अन्य कोड कॉलबैक रजिस्टर कर सकें या वर्तमान स्थिति का निरीक्षण कर सकें।

बस हम कह सकते हैं कि एक वादा एक ऐसे मूल्य का प्रतिनिधित्व करता है जो अभी तक ज्ञात नहीं है जहां एक आस्थगित काम का प्रतिनिधित्व करता है जो अभी तक समाप्त नहीं हुआ है।


यहां छवि विवरण दर्ज करें


1
चार्ट प्रतिनिधित्व के लिए प्लस 1। Bravisimo !! ^ _ ^
अशोक एमए

23
  • A promiseऐसे मान का प्रतिनिधित्व करता है जो अभी तक ज्ञात नहीं है
  • एक deferredकाम का प्रतिनिधित्व करता है जो अभी तक समाप्त नहीं हुआ है

एक वादा एक परिणाम के लिए एक प्लेसहोल्डर है जो शुरू में अज्ञात है जबकि एक आस्थगित गणना में मूल्य के परिणामस्वरूप गणना का प्रतिनिधित्व करता है।

संदर्भ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.