एक वादे के मूल्य का उपयोग कैसे करें?


146

मैं इस उदाहरण को एंगुलर के डॉक्स से देख रहा हूं, $qलेकिन मुझे लगता है कि यह सामान्य तौर पर वादों पर लागू होता है। नीचे दिए गए उदाहरण को उनकी टिप्पणी के साथ उनके डॉक्स से शब्दशः कॉपी किया गया है:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

मैं स्पष्ट नहीं हूं कि यह कैसे काम करता है। यदि मैं .then()पहले परिणाम पर कॉल कर सकता .then()हूं, तो उनका पीछा करना, जो मुझे पता है कि मैं कर सकता हूं, तो promiseBएक वादा वस्तु है, प्रकार का Object। यह एक नहीं है Number। तो उन्हें "1 से बढ़े हुए वादे का परिणाम क्या होगा" से क्या मतलब है?

क्या मुझे उस promiseB.valueया उस तरह से एक्सेस करना चाहिए ? कैसे सफलता कॉलबैक एक वादा वापस कर सकता है और "परिणाम + 1" लौटा सकता है? मुझे कुछ याद आ रहा है।




यह प्रश्न 5 वर्ष पुराना है और इसका एक स्वीकृत उत्तर है ...
अस्थायी_सुमेर_

@temporary_user_name: पुराने प्रश्नों पर भी, किसी भी समय करीबी वोट डालना लोगों के लिए ठीक है।
रोकें

जवाबों:


141

promiseAके thenसमारोह में एक नया वादा (रिटर्न promiseB) है कि तुरंत बाद हल हो गई है promiseAहल हो गई है, अपने मूल्य क्या भीतर सफलता समारोह से वापस आ रहा है का मूल्य है promiseA

इस मामले promiseAमें एक मूल्य के साथ हल किया जाता है - resultऔर फिर तुरंत promiseBके मूल्य के साथ हल होता है result + 1

के मूल्य तक पहुँच promiseBउसी तरह से किया जाता है जिस तरह से हम के परिणाम तक पहुँचते हैं promiseA

promiseB.then(function(result) {
    // here you can use the result of promiseB
});

दिसंबर 2019 को संपादित करें : async/ awaitअब जेएस में मानक है, जो ऊपर वर्णित दृष्टिकोण के लिए एक वैकल्पिक वाक्यविन्यास की अनुमति देता है। अब आप लिख सकते हैं:

let result = await functionThatReturnsPromiseA();
result = result + 1;

अब कोई वादा नहीं है, क्योंकि हमने वादे का उपयोग करके परिणाम को रद्द कर दिया है await, और आप इसके साथ सीधे काम कर सकते हैं।

हालांकि, awaitकेवल एक asyncफ़ंक्शन के अंदर उपयोग किया जा सकता है । तो थोड़ा बाहर ज़ूम करने के लिए, उपरोक्त को इसमें शामिल करना होगा:

async function doSomething() {
    let result = await functionThatReturnsPromiseA();
    return result + 1;
}

2
वादे सैद्धांतिक रूप से उनकी अपनी वस्तुएं हैं। उनमें एक परिणाम होता है जिसे वादे की सफलता के माध्यम से पहुँचा जा सकता है।
नचशोन श्वार्ट्ज

2
इसलिए यदि आप किसी वादे के एसिंक्रोनस कॉलबैक के रिटर्न वैल्यू के साथ काम करना चाहते हैं, तो उसे दूसरे एसिंक्रोनस कॉलबैक के अंदर करना होगा। समझ में आता है। मैं कुछ परम आदिम वापसी मूल्य प्राप्त करने के लिए एक रास्ता तलाश रहा था लेकिन मुझे लगता है कि संदर्भ को देखते हुए अवहेलना करेगा।
temporary_user_name

2
@Aerovistae वास्तव में, ES6 जनरेटर का परिचय देता है जो इसे संभव बनाता है और ES7 async फ़ंक्शंस का परिचय देता है - दोनों आपको उन वादों पर सिंटेक्स शुगर देते हैं जो इसे सिंक्रोनस कोड (पृष्ठभूमि में एक राज्य मशीन चलाकर) जैसा दिखता है - इसलिए कसकर पकड़ें :)
बेंजामिन Gruenbaum

25

जब कोई वादा हल / अस्वीकार किया जाता है, तो वह अपनी सफलता / त्रुटि हैंडलर कहेगा:

var promiseB = promiseA.then(function(result) {
   // do something with result
});

thenPromiseB, जो / अस्वीकार का समाधान हो जाएगा: विधि भी एक वादा रिटर्न promiseA से सफलता / त्रुटि हैंडलर से लौटने के मूल्य के आधार पर

तीन संभावित मूल्य हैं जो वादे की सफलता / त्रुटि हैंडलर वापस कर सकते हैं जो वादे के परिणाम को प्रभावित करेगा:

1. Return nothing --> PromiseB is resolved immediately, 
   and undefined is passed to the success handler of promiseB
2. Return a value --> PromiseB is resolved immediately,
   and the value is passed to the success handler of promiseB
3. Return a promise --> When resolved, promiseB will be resolved. 
   When rejected, promiseB will be rejected. The value passed to
   the promiseB's then handler will be the result of the promise

इस समझ के साथ, आप निम्नलिखित की समझ बना सकते हैं:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

तत्कालीन कॉल प्रतिज्ञा को तुरंत वापस करती है। जब वादे का समाधान हो जाता है, तो यह वादा करने वाले के सफल हैंडलर को परिणाम देगा। चूंकि रिटर्न वैल्यू वादा 1 का परिणाम है + 1, सफलता हैंडलर एक मान (विकल्प 2 ऊपर) लौटा रहा है, इसलिए वादाबी तुरंत हल करेगा, और वादाबी का सफलता हैंडलर वादा 1 का परिणाम पारित किया जाएगा।


4

.thenवादा का कार्य प्राप्त करता है जो वादे के कार्य से वापस आ .thenजाता है।

यहाँ वादा एक रिटर्न एक संख्या है, जो numberवादे के सफलता समारोह में पैरामीटर के रूप में उपलब्ध होगी । जो तब 1 से बढ़ जाएगा


3

आपकी वर्तमान समझ की तुलना में टिप्पणी को थोड़ा अलग तरीके से प्रस्तुत करने से मदद मिल सकती है:

// promiseB will be resolved immediately after promiseA is resolved

यह बताता है कि promiseBएक वादा है लेकिन हल होने के तुरंत बाद promiseAहल हो जाएगा। इसे देखने का एक और तरीका है, जो promiseA.then()एक वादा लौटाता है जिसे सौंपा गया है promiseB

// and its value will be the result of promiseA incremented by 1

इसका मतलब यह है कि मूल्य जो promiseAहल किया गया है वह मूल्य है जो promiseBउसके उत्तराधिकार मूल्य के रूप में प्राप्त होगा:

promiseB.then(function (val) {
  // val is now promiseA's result + 1
});

2

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

हालाँकि, निम्नलिखित असमर्थित आंतरिक नोड का उपयोग करके इसे हल करने के बाद सीधे वादे के मूल्य तक पहुँचने का एक तरीका है।

process.binding('util').getPromiseDetails(myPromise)[1]

चेतावनी: प्रोसेस.बाइंडिंग का उपयोग कभी भी नोडज कोर के बाहर करने के लिए नहीं किया गया था और नोड्ज कोर टीम सक्रिय रूप से इसे हटाना चाह रही है

https://github.com/nodejs/node/pull/22004 https://github.com/nodejs/node/issues/22064


1

यह उदाहरण मुझे आत्म-व्याख्यात्मक लगता है। ध्यान दें कि परिणाम का इंतजार कैसे किया जाता है और इसलिए आप वादा किए गए को वापस करने से चूक जाते हैं।

cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}

यह एक async फ़ंक्शन में होना चाहिए।
सैम

0
promiseA(pram).then(
     result => { 
     //make sure promiseA function allready success and response
     //do something here
}).catch(err => console.log(err)) => {
     // handle error with try catch
}

1
इस कोड को इस सवाल का जवाब कर सकते हैं, के बारे में अतिरिक्त संदर्भ प्रदान करने के लिए कैसे और क्यों यह हल करती है समस्या जवाब की दीर्घकालिक मूल्य में सुधार होगा।
सिकंदर

0

आप जावास्क्रिप्ट में एक async प्रतीक्षा पद्धति का उपयोग करके आसानी से कर सकते हैं।

नीचे एक उदाहरण का उपयोग करके एक WebRTC वादा मूल्य प्राप्त किया जाता है जो टाइमआउट का उपयोग करता है।

function await_getipv4(timeout = 1000) {
    var t1 = new Date();
    while(!window.ipv4) {
        var stop = new Date() - t1 >= timeout;
        if(stop) {
            console.error('timeout exceeded for await_getipv4.');
            return false;
        }
    }
    return window.ipv4;
}

function async_getipv4() {
    var ipv4 = null;
    var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
    findIP.then(ip => window.ipv4 = ip);
    return await_getipv4();
};


इस स्निपेट को यहां नहीं बल्कि एक वास्तविक ब्राउज़र में चलाना महत्वपूर्ण है, मेरा मानना ​​है कि यह सैंडबॉक्सिंग के कारण है।
ऑक्सफेफैस

0

नोड REPL में, एक DB कनेक्शन प्राप्त करने के लिए जो एक वादे का मूल्य था, मैंने निम्नलिखित दृष्टिकोण लिया:

let connection
try {
  (async () => {
    connection = await returnsAPromiseResolvingToConnection()
  })()
} catch(err) {
  console.log(err)
}

awaitआमतौर पर एक वादा के साथ लाइन वापस आ जाएगी। इस कोड को नोड REPL में चिपकाया जा सकता है या यदि इसमें सहेजा गया है तो index.jsइसे Bash के साथ चलाया जा सकता है

node -i -e "$(< index.js)"

जो सेट चर के उपयोग के साथ स्क्रिप्ट चलाने के बाद आपको नोड REPL में छोड़ देता है। यह पुष्टि करने के लिए कि एसिंक्रोनस फ़ंक्शन वापस आ गया है, आप connectionउदाहरण के लिए लॉग इन कर सकते हैं , और फिर आप चर का उपयोग करने के लिए तैयार हैं। बेशक अतुल्यकालिक समारोह के बाहर स्क्रिप्ट में किसी भी कोड के लिए अभी तक हल किए जा रहे अतुल्यकालिक समारोह पर भरोसा नहीं करना चाहते हैं।


0

ऊपर कुछ अच्छे उत्तर हैं और यहां ES6 एरो फ़ंक्शन संस्करण है

var something = async() => {
   let result = await functionThatReturnsPromiseA();
   return result + 1;
}

0

मैं जावास्क्रिप्ट वादों का एक धीमा जानने वाला हूं, डिफ़ॉल्ट रूप से सभी async फ़ंक्शंस एक वादा वापस करते हैं, आप अपना परिणाम इस तरह से लपेट सकते हैं:

(async () => {
//Optional "await"
  await yourAsyncFunctionOrPromise()
    .then(function (result) {
      return result +1;
    })
    .catch(function (error) {
      return error;
    })()
})

" प्रतीक्षारत अभिव्यक्ति के कारण async फ़ंक्शन निष्पादन तब तक रुक जाता है जब तक कि एक वादा (यानी पूरा या अस्वीकृत) का निपटान नहीं किया जाता है, और पूर्ति के बाद async फ़ंक्शन के निष्पादन को फिर से शुरू करने के लिए। जब ​​फिर से शुरू किया जाता है, तो प्रतीक्षित अभिव्यक्ति का मूल्य पूर्ण किए गए वादा का होता है। । अगर वादा खारिज कर दिया जाता है, तो प्रतीक्षित अभिव्यक्ति अस्वीकृत मूल्य को फेंक देती है । "

MDN वेब डॉक्स पर प्रतीक्षा और वादों के बारे में और पढ़ें


-5

शायद यह छोटा टाइपस्क्रिप्ट कोड उदाहरण मदद करेगा।

private getAccount(id: Id) : Account {
    let account = Account.empty();
    this.repository.get(id)
        .then(res => account = res)
        .catch(e => Notices.results(e));
    return account;
}

यहाँ repository.get(id)रिटर्न ए Promise<Account>। मैं इसे स्टेटमेंट के accountभीतर वेरिएबल पर असाइन करता हूं then


1
प्रॉमिस को हल करने से पहले आपका कोड वापस आ रहा है और यही कारण है कि यह डाउन वोट किया गया है, आपका कोड हमेशा खाता रहता है। खाली ();
फाल्के डे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.