किसी फ़ंक्शन के चर को वापस करने से पहले मैं एक वादा पूरा करने के लिए कैसे प्रतीक्षा करूं?


149

मैं अभी भी वादों से जूझ रहा हूं, लेकिन यहां समुदाय के लिए कुछ प्रगति कर रहा हूं।

मेरे पास एक सरल जेएस फ़ंक्शन है जो पार्स डेटाबेस पर सवाल उठाता है। यह परिणामों की सरणी को वापस करने वाला है, लेकिन जाहिर है क्वेरी की अतुल्यकालिक प्रकृति (इसलिए वादों) के कारण, फ़ंक्शन परिणामों से पहले वापस आ जाता है, मुझे एक अपरिभाषित सरणी के साथ छोड़ देता है।

इस फ़ंक्शन को वादे के परिणाम की प्रतीक्षा करने के लिए मुझे क्या करने की आवश्यकता है?

यहाँ मेरा कोड है:

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    var promise = query.find({
               success: function(results) {
               // results is an array of Parse.Object.
                             console.log(results);
                             //resultsArray = results;
                             return results;
               },

               error: function(error) {
               // error is an instance of Parse.Error.
                             console.log("Error");
               }
    });                           

}

3
आप async / प्रतीक्षा का उपयोग करने पर भी विचार कर सकते हैं। नोड अब संस्करण 7.6 से बॉक्स के बाहर async / प्रतीक्षा का समर्थन करता है
विलिअम सिमको

जवाबों:


66

बदले में resultsArrayआप एक परिणाम सरणी के लिए एक वादा वापस करते हैं और फिर thenकॉल साइट पर - यह कॉल करने वाले का अतिरिक्त लाभ है यह जानते हुए कि फ़ंक्शन असिंक्रोनस I / O का प्रदर्शन कर रहा है। जावास्क्रिप्ट में कोडिंग संगामिति आधारित है - आप एक व्यापक विचार प्राप्त करने के लिए इस प्रश्न को पढ़ना चाह सकते हैं :

function resultsByName(name)
{   
    var Card = Parse.Object.extend("Card");
    var query = new Parse.Query(Card);
    query.equalTo("name", name.toString());

    var resultsArray = [];

    return query.find({});                           

}

// later
resultsByName("Some Name").then(function(results){
    // access results here by chaining to the returned promise
});

आप इसके बारे में पार्स के अपने ब्लॉग पोस्ट में प्रश्नों के साथ पार्स वादों का उपयोग करने के अधिक उदाहरण देख सकते हैं ।


क्या आप मुझे बता सकते हैं कि इसका समर्थन क्या है? IE9 यह समर्थन करता है?
सैंड्रीना-पी

हां, लेकिन पारसे खुद ही ज्यादातर मर चुकी है इसलिए @SandrinaPereira है। यह पार्स क्लाउड कोड है।
बेंजामिन ग्रुएनबाम

1
इसलिए यह केवल शुद्ध जावास्क्रिप्ट नहीं है? मैं ऐसा करने के लिए एक रास्ता तलाश रहा था (एक समारोह शुरू करने के लिए प्रतीक्षा करने के लिए) एक और शुरू करने के लिए लेकिन केवल शुद्ध जावास्क्रिप्ट के साथ ..
सैंड्रीना-पी

सवाल पार्स कोड के बारे में है, वादों का नहीं। वादे किसी भी ब्राउज़र में (एक पुस्तकालय के साथ) काम कर सकते हैं। ब्लूबर्ड IE6 में चलता है और नेटस्केप 7.
बेंजामिन ग्रुएनबाउम

1
मैं अब दो दिनों से एसओ पढ़ रहा हूं, और अभी भी, किसी ने भी इसे हल नहीं किया है। यह स्वीकृत उत्तर हर दूसरे के समान है। फ़ंक्शन एक वादा लौटाता है, न कि ओपी द्वारा अनुरोधित मूल्य। इस उत्तर को क्यों स्वीकार किया गया है?
यज्ञजा

19

इस फ़ंक्शन को वादे के परिणाम की प्रतीक्षा करने के लिए मुझे क्या करने की आवश्यकता है?

async/awaitECMA6 का उपयोग न करें (2017 के अंत से क्रोम, एज, फ़ायरफ़ॉक्स और सफारी के लिए उपलब्ध है, देखें canIuse )
MDN

    async function waitForPromise() {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

टिप्पणी के कारण जोड़ा गया: एक async फ़ंक्शन हमेशा एक वादा देता है, और टाइपस्क्रिप्ट में यह ऐसा दिखेगा:

    async function waitForPromise(): Promise<string> {
        // let result = await any Promise, like:
        let result = await Promise.resolve('this is a sample promise');
    }

4
यदि कोई प्रतीक्षा किए बिना (या गैर अतुल्यकालिक कोड में) async फ़ंक्शन अभी भी एक वादा ऑब्जेक्ट लौटाएगा। यदि आप अनिश्चित हैं, तो कंसोल.लॉग (waForPromise ()) के परिणाम की जाँच करें। Async फ़ंक्शन के भीतर कंसोल.लॉग (परिणाम) की एक जांच से आप जो उम्मीद करते हैं वह प्रिंट हो जाएगा , लेकिन async फ़ंक्शन से वापसी बिना ब्लॉक किए तुरंत हो जाती है और एक वादा वापस करती है। जावास्क्रिप्ट में ब्लॉकिंग आमतौर पर बहुत खराब होती है क्योंकि यह एक एकल थ्रेडेड एप्लिकेशन है और ब्लॉकिंग किसी भी अन्य पब / नोटिफिकेशन के क्लाइंट को भूखा रखेगा और अनिवार्य रूप से पूरे ऐप को घुटनों पर ला देगा।
एसआरएम

1
.net में .wait () टास्क क्लास की तरह "वादा" है। क्या जावास्क्रिप्ट इस सुविधा को याद कर रहा है? मुझे अपने नोड कमांड-लाइन टूल से बाहर निकलने से पहले कुछ इंतजार करना होगा जो इसके आउटपुट को दूसरे टूल पर पाइप कर सकता है। "इंतजार" केवल async कार्यों के अंदर काम करता है। मतलब यह किसी वादे के दायरे से बाहर काम नहीं करता है।
तामूसरायूस

@ एसआरएम मुझे ऐसा लगता है कि आपकी टिप्पणी नमूने की गलत व्याख्या पर आधारित है - यह "इनर" प्रॉमिस.आर्सोल (सबसे सरल वादा उदाहरण के रूप में) के बारे में है, इसलिए कोई बाहरी कॉलर नहीं है क्योंकि आप अपनी टिप्पणी में बता रहे हैं। इसलिए मैंने जवाब अपडेट करने का फैसला किया।
मार्टिन मेसर

@TamusJRoyce लगता है कि अपने आप में एक सवाल है, लेकिन मुझे लगता है कि C # में आप Task.ContinueWith (टास्क) का उपयोग कर सकते हैं, जो कि एक ही विचार है जैसा कि आप स्वीकृत उत्तर में देखते हैं (जहां इसे "तब" ("") कहा जाता है।
मार्टिन मेसेर

मुझे लगता है कि अब मैं देख रहा हूं। मैं एक बहुत बड़े async फ़ंक्शन में अपनी पूरी स्क्रिप्ट को बहुत लपेट सकता हूं। और उस फ़ंक्शन को मेरी स्क्रिप्ट की अंतिम पंक्ति के रूप में कॉल करें। यह फ़ंक्शन अभी भी बॉयलर प्लेट का थोड़ा सा होगा। लेकिन जिस तरह से मैं पहले से कम माना जाता है। मुझे फ़ंक्शन के भीतर फ़ंक्शन लिखने की आदत नहीं है। धन्यवाद @MartinMeeser!
तामसुजयर्स

3

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

var promise = query.find(); 
return promise; 

//Or return query.find(); 

1
success:बिट के साथ आपकी पूरी कॉलबैक चीज़ बंद है।
बेंजामिन ग्रुएनबाम

या बेहतर return query.find();:।
मैश

यह भी ठीक है। मैं इसे केवल इस उद्देश्य के लिए छोड़ दूंगा लेकिन इसे टिप्पणी के रूप में जोड़ा।
ट्रेस

मैंने यह कोशिश की लेकिन परिणाम अपरिभाषित प्रतीत होते हैं। resultsByName ("नाम")। तब (फ़ंक्शन (परिणाम) {कंसोल.लॉग ("एरे मिला" + + ..count);});
mac_55

1
धन्यवाद, परिणाम फ़ंक्शन के अंदर किसी प्रकार की त्रुटि रही होगी। अब यह काम कर रहा है। मैंने अपना कंसोल.लॉग बदलकर results.length और देखा कि मेरे लौटे सरणी में 1 प्रविष्टि है :)
mac_55

2

आप वास्तव में यहां वादों का उपयोग नहीं कर रहे हैं। पार्स आपको कॉलबैक या वादों का उपयोग करने देता है; आपकी पसंद।

वादों का उपयोग करने के लिए, निम्नलिखित करें:

query.find().then(function() {
    console.log("success!");
}, function() {
    console.log("error");
});

अब, वादा पूरा होने के बाद सामान को निष्पादित करने के लिए, आप बस इसे वादा कॉलबैक के अंदर निष्पादित कर सकते हैं then() कॉल के हैं। अब तक यह नियमित कॉलबैक के समान ही होगा।

वास्तव में वादों का अच्छा उपयोग करने के लिए जब आप उन्हें इस तरह से चेन करते हैं:

query.find().then(function() {
    console.log("success!");

    return new Parse.Query(Obj).get("sOmE_oBjEcT");
}, function() {
    console.log("error");
}).then(function() {
    console.log("success on second callback!");
}, function() {
    console.log("error on second callback");
});

परिणाम वस्तु किस प्रकार की वस्तु है? क्योंकि इसमें मेरी सरणी नहीं लगती है
mac_55

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