उसके बाद से रिटर्न वैल्यू या Promise.resolve के बीच क्या अंतर है


314

के बीच क्या अंतर है:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return "bbb";
  })
  .then(function(result) {
    console.log(result);
  });

और इस:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });

जैसा कि मैं पूछ रहा हूँ कि मैं अलग-अलग व्यवहार कर रहा हूँ। थोड़ा बहुत कोड इसलिए पहले उदाहरण ऊपर।


1
आप "अलग व्यवहार" क्या देख रहे हैं? दोनों उदाहरणों को काम करना चाहिए और लगभग समान व्यवहार करना चाहिए। Promise.resolve()दूसरे उदाहरण में अनावश्यक है।
JLRishe

4
@pixelbits एक thenहैंडलर से एक वादा वापस करने के साथ कुछ भी गलत नहीं है, वास्तव में, यह वादों की कल्पना का एक प्रमुख पहलू है जो आप कर सकते हैं।

ध्यान दें कि यह मनमाने ढंग से नेस्टेड thenएस के साथ काम करता है - इसके लिए 'अन्य भाषाएं' शब्द thenएक mapऔर एक दोनों है flatMap
बेंजामिन Gruenbaum

1
पंक्ति 2 में आपको रेस ("आआ") क्यों बुलाना है, "अआ" को वापस क्यों नहीं ला सकते हैं और संकल्प के लिए प्रॉमिस कैच () इसे उसी तरह से है कि यह अस्वीकार के लिए अपवादों को पकड़ता है ()?
सैम लिडिकॉट

1
@SamLiddicott में एक ही प्रश्न है, जबकि खदानें थोड़ी अधिक जटिल हैं: new Promise((res, rej) => { return fetch('//google.com').then(() => { return "haha"; }) }).then((result) => alert(result));यह कोड बस लटका रहेगा (हमेशा के लिए हल नहीं किया गया)। लेकिन अगर मैं बदल return "haha";जाता हूं return res("haha");तो यह काम करेगा और "हाहा" को सतर्क करेगा। क्या भ्रूण () नहीं था। तब () पहले से ही हल किए गए वादे में "हाहा" लपेटता है?
शांग चेंग

जवाबों:


138

नियम यह है कि यदि फ़ंक्शन जो thenहैंडलर में है वह मान लौटाता है, तो वादा उस मूल्य के साथ हल / अस्वीकार करता है, और यदि फ़ंक्शन एक वादा लौटाता है, तो क्या होता है, अगला thenक्लॉज उस वादेthen का खंड होगा जिसे फ़ंक्शन ने वापस कर दिया है , इसलिए, इस मामले में, पहला उदाहरण सामान्य अनुक्रम के माध्यम से गिरता है thensऔर मूल्यों को प्रिंट करता है जैसा कि कोई उम्मीद कर सकता है, दूसरे उदाहरण में, वादा वस्तु जो तब वापस आती है जब आप ऐसा करते हैं Promise.resolve("bbb"), तो यह है thenकि पीछा करते समय आह्वान किया जाता है (सभी उद्देश्यों और इरादों के लिये)। जिस तरह से यह वास्तव में काम करता है वह नीचे और अधिक विवरण में वर्णित है।

वादे / ए + युक्ति से उद्धरण:

वादा समाधान प्रक्रिया एक अमूर्त ऑपरेशन है जो इनपुट के रूप में एक वादा और एक मूल्य है, जिसे हम निरूपित करते हैं [[Resolve]](promise, x)यदि xयह उचित है, तो यह वादा करने की कोशिश करता है कि इस स्थिति कोx स्वीकार किया जाए, इस धारणा के तहत कि x कम से कम कुछ वादे की तरह व्यवहार करता है । अन्यथा, यह मूल्य के साथ वादा पूरा करता है x

तबेबल्स के इस उपचार से वादे के क्रियान्वयन को बीच में लाने की अनुमति मिलती है, जब तक वे एक वादा / ए + -कंप्लीटेंट तब विधि को उजागर करते हैं। यह वादा करता है / ए + कार्यान्वयन के लिए उचित तो तरीकों के साथ गैर-अनुरूप कार्यान्वयन को "आत्मसात" करने की अनुमति देता है।

यहाँ ध्यान देने योग्य बात यह है कि यह लाइन है:

अगर xएक वादा है, तो अपना राज्य अपनाएं [3.4]

लिंक: https://promisesaplus.com/#point-49


4
"अपना राज्य अपनाना" व्यवहार को व्यक्त करने के लिए एक संक्षिप्त और उपयोगी तरीका है जब एक thenहैंडलर वादा करता है। कल्पना संदर्भ के लिए +1।

69
वास्तव में - यहाँ युक्ति का प्रासंगिक भाग वह तथ्य [[Resolve]]है जिसे thenएब्स और वैल्यू दोनों पर कहा जाता है, इसलिए यह मूल रूप से वादे के साथ एक वैल्यू लपेटता return "aaa"है, जैसा है वैसा ही है return Promise.resolve("aaa")और return Promise.resolve("aaa")जैसा है return Promise.resolve(Promise.resolve("aaa"))- चूंकि संकल्प एक मान पर इसे अधिक कहते हैं एक बार की तुलना में एक ही परिणाम है।
बेंजामिन ग्रुएनबाम

8
@ बेंजामिन ग्रुएनबाम का मतलब यह है कि वापसी "aaa"और किसी भी मामले return Promise.resolve("aaa")में thenएबल्स में विनिमेय हैं ?
CSnerd

9
हां, इसका ठीक यही मतलब है।
बेंजामिन ग्रुएनबाम

118

सरल शब्दों में, एक thenहैंडलर फ़ंक्शन के अंदर :

ए) जब xएक मान (संख्या, स्ट्रिंग, आदि) है:

  1. return x के बराबर है return Promise.resolve(x)
  2. throw x के बराबर है return Promise.reject(x)

बी) जब xएक वादा है जो पहले से ही तय है (अब लंबित नहीं है):

  1. return xके बराबर है return Promise.resolve(x), अगर वादा पहले ही हल हो गया था।
  2. return xके बराबर है return Promise.reject(x), अगर वादा पहले ही खारिज कर दिया गया था।

ग) जब xएक वादा लंबित है:

  1. return xएक लंबित वादा वापस करेगा, और इसका मूल्यांकन बाद में किया जाएगा then

इस विषय पर और अधिक पढ़ें Promise.prototyp.then () डॉक्स


92

आपके दोनों उदाहरणों में बहुत समान व्यवहार होना चाहिए।

then()हैंडलर के अंदर लौटाया गया मान उसी से लौटाए गए वादे का संकल्प मूल्य बन जाता है then()। यदि मूल्य के अंदर लौटाया गया .then वादा है, तो वादा किया गया वादा then()उस राज्य को "गोद लेगा" और उस वादे को हल / अस्वीकार कर देगा जैसा कि लौटा हुआ वादा करता है।

अपने पहले उदाहरण में, आप "bbb"पहले then()हैंडलर में लौटते हैं , इसलिए "bbb"अगले then()हैंडलर में पास किया जाता है ।

अपने दूसरे उदाहरण में, आप एक वादा वापस करते हैं जो मूल्य के साथ तुरंत हल हो जाता है "bbb", इसलिए "bbb"अगले then()हैंडलर में पारित किया जाता है । ( Promise.resolve()यहाँ पर विलुप्त है)।

परिणाम वही है।

यदि आप हमें एक उदाहरण दिखा सकते हैं जो वास्तव में अलग व्यवहार प्रदर्शित करता है, तो हम आपको बता सकते हैं कि ऐसा क्यों हो रहा है।


1
अच्छा उत्तर! Promise.resolve();बनाम के बारे में क्या return;?
फेबियनटी

2
@FabianTe उन पर भी समान प्रभाव होगा, इसके undefinedबजाय के साथ "bbb"
JLRishe

51

आपको पहले से ही एक अच्छा औपचारिक जवाब मिल गया था। मुझे लगा कि मुझे एक छोटा जोड़ना चाहिए।

निम्नलिखित बातें वादे / ए + वादों के साथ समान हैं :

  • कॉलिंग Promise.resolve(अपने कोणीय मामले में $q.when)
  • वादे करने वाले को बुलाना और अपनी रिवाल्वर में हल करना। आपके मामले में ऐसा है new $q
  • thenकॉलबैक से मान वापस करना ।
  • एक मूल्य के साथ एक सरणी पर Promise.all को कॉल करना और फिर उस मान को निकालना।

तो एक वादा या सादा मूल्य X के लिए सभी समान हैं:

Promise.resolve(x);
new Promise(function(resolve, reject){ resolve(x); });
Promise.resolve().then(function(){ return x; });
Promise.all([x]).then(function(arr){ return arr[0]; });

और यह कोई आश्चर्य की बात नहीं है, वादे के विनिर्देश प्रॉमिस रिज़ॉल्यूशन प्रक्रिया पर आधारित है जो पुस्तकालयों (जैसे $ q और मूल वादों) के बीच आसान व्यवधान को सक्षम बनाता है और आपके जीवन को समग्र रूप से आसान बनाता है। जब भी एक वादा संकल्प हो सकता है एक संकल्प समग्र स्थिरता बनाने होता है।


क्या मैं पूछ सकता हूं कि क्या करने की बात है Promise.resolve().then(function(){ return x; });? मैंने कुछ ऐसा ही करते हुए एक स्निप पाया (इसे thenब्लॉक के अंदर एक फ़ंक्शन कहा जाता है )। मुझे लगा कि यह कमोबेश टाइमआउट करने जैसा है, लेकिन यह थोड़ा तेज है। jsben.ch/HIfDo
सम्पगन

99.99% मामलों में Promise.resolve (x) के समान ही कोई बिंदु नहीं है। (0.001% यह है कि हम withकिसी ऑब्जेक्ट या प्रॉक्सी पर एक xप्रॉपर्टी एक्सेसर के साथ एक ब्लॉक में हैं, जो एक अपवाद को फेंकता है। उस स्थिति में Promise.resolve (x) एक थ्रो एरर का कारण बनेगा, लेकिन Promise.resolve().then(function(){ return x; });त्रुटि को फेंकने के बाद एक अस्वीकृत वादा होगा। ए then) में।
बेंजामिन ग्रुएनबाम

आपने एक खाली ब्लिट्ज लिंक किया, या आपने सहेजा नहीं। वैसे भी मैं बयानों के बीच मतभेदों के बारे में बात नहीं कर रहा था। मैंने जो लिखा उसके बारे में ठीक-ठीक बात कर रहा था। बस अधिक स्पष्ट होने के लिए, यह स्निपेट है जिसके बारे में मैं बात कर रहा था if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }:। यहाँ वादा नहीं सौंपा गया है, तो क्या बात है? एक टाइमआउट का (कमोबेश) एक ही प्रभाव होगा, या नहीं?
संपागन

1
यह सभी सिंक्रोनस कोड होने के बाद भी एसिंक्रोनस रूप से कॉल करता है लेकिन किसी भी I / O के होने से पहले। इसे "माइक्रोटीक शब्दार्थ" कहा जाता है।
बेंजामिन ग्रुएनबाम

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