इंतजार केवल async फ़ंक्शन में मान्य है


130

में यह कोड लिखा था lib/helper.js

var myfunction = async function(x,y) {
   ....
   reutrn [variableA, variableB]
}
exports.myfunction = myfunction;

और फिर मैंने इसे दूसरी फाइल में इस्तेमाल करने की कोशिश की

 var helper = require('./helper.js');   
 var start = function(a,b){
     ....
     const result = await helper.myfunction('test','test');
 }
 exports.start = start;

मुझे एक त्रुटि मिली

"async फ़ंक्शन में प्रतीक्षा केवल मान्य है"

मामला क्या है?


1
खैर, मुद्दा यह है कि awaitकेवल एक asyncफ़ंक्शन के अंदर उपयोग किया जा सकता है । यही है, awaitएक फ़ंक्शन को अतुल्यकालिक बनाता है, इसलिए इसे इस तरह से घोषित किया जाना चाहिए।
पॉइन्टी

वर्तमान त्रुटि क्या है?
acdcjunior

अभी भी एक ही है,
सिंटेक्स एरर

आपको अपने कोड के बारे में अधिक संदर्भ साझा करने की आवश्यकता है।
हाथी

जवाबों:


160

त्रुटि को संदर्भित नहीं है, myfunctionलेकिन करने के लिए start

async function start() {
   ....

   const result = await helper.myfunction('test', 'test');
}

// My function
const myfunction = async function(x, y) {
  return [
    x,
    y,
  ];
}

// Start function
const start = async function(a, b) {
  const result = await myfunction('test', 'test');
  
  console.log(result);
}

// Call start
start();



मैं एक जाना जाता विरोधी पद्धति का उपयोग कर के बारे में सलाह देने के लिए इस सवाल का अवसर का उपयोग awaitहै जो: return await


गलत

async function myfunction() {
  console.log('Inside of myfunction');
}

// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later

// useless async here
async function start() {
  // useless await here
  return await myfunction();
}

// Call start
(async() => {
  console.log('before start');

  await start();
  
  console.log('after start');
})();


सही बात

async function myfunction() {
  console.log('Inside of myfunction');
}

// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later

// Also point that we don't use async keyword on the function because
// we can simply returns the promise returned by myfunction
function start() {
  return myfunction();
}

// Call start
(async() => {
  console.log('before start');

  await start();
  
  console.log('after start');
})();


यह भी जान लें कि एक विशेष मामला है जहां return awaitसही और महत्वपूर्ण है: (कोशिश / पकड़ का उपयोग करके)

क्या awa रिटर्न वेट ’के साथ प्रदर्शन की चिंताएं हैं?


लेकिन यह काम नहीं कर रहा है, मैंने अपना कोड अपडेट कर दिया है। मुझे अभी भी वही त्रुटि
मिलती है

@ j.doe मैंने एक स्निपेट जोड़ा है
Grégory NEUT

2
धन्यवाद, मुझे मेरी समस्या मिल गई। मैं इसे कॉलबैक के अंदर करने की कोशिश कर रहा था जो कि स्टार्ट () फंक्शन है। इसका हल था: const start = async function (a, b) {task.get (विकल्प, async function (error, result1) {const result = इंतजार myfunction ('परीक्षण', 'परीक्षण');
j.doe

यह मानते हुए कि नोड एक एकल पिरोया हुआ है। क्या यह प्रति मिनट अनुरोध कम नहीं करता है और फुलफिलिंग अनुरोधों के बीच देरी को भी बढ़ाता है।
ऋषभ धीमान

1
यह ध्यान देने योग्य है कि "CORRECT" उदाहरण में, startएक asyncफ़ंक्शन के रूप में घोषित करना आवश्यक नहीं है (हालांकि कुछ ने वैसे भी ऐसा करने के लिए चुना होगा, ताकि अधिक स्पष्ट हो सके)
गेर्शोम

11

जब मुझे यह त्रुटि मिली, तो यह पता चला कि मेरे "async" फ़ंक्शन के अंदर मैप फ़ंक्शन के लिए मेरे पास एक कॉल था, इसलिए यह त्रुटि संदेश वास्तव में मैप फ़ंक्शन को "async" के रूप में चिह्नित नहीं होने का उल्लेख कर रहा था। मैं इस मुद्दे को मैप फ़ंक्शन से "वेट" कॉल लेने और अपेक्षित व्यवहार प्राप्त करने के कुछ अन्य तरीके के साथ आ रहा था।

var myfunction = async function(x,y) {
    ....
    someArray.map(someVariable => { // <- This was the function giving the error
        return await someFunction(someVariable);
    });
}

2
मेरे लिए यही समस्या थी। मैंने मानचित्र फ़ंक्शन को एक लूप के साथ बदल दिया, जो मेरे लिए एक आसान समाधान था। हालाँकि, यह समाधान आपके कोड के आधार पर आपके लिए काम नहीं कर सकता है।
थॉमस

6
FYI करें आप भी कर सकते हैंsomeArray.map(async (someVariable) => { return await someFunction(someVariable)})
ptim

1
awaitअपने कोड में, भ्रामक है क्योंकि Array.mapएक अतुल्यकालिक समारोह के रूप में समारोह को संभाल नहीं होंगे। पूरी तरह से स्पष्ट होने के लिए, mapकार्य समाप्त होने के बाद , someFunctionसभी लंबित हो जाएंगे। यदि आप वास्तव में कार्यों को समाप्त करने के लिए इंतजार करना चाहते हैं तो आपको लिखना होगा: await Promise.all(someArray.map(someVariable => someFunction(someVariable)))या await Promise.all(someArray.map(someFunction)))
ग्रेजोरी NEUT

9

उपयोग करने के लिए await, इसका निष्पादन संदर्भ asyncप्रकृति में होना चाहिए

जैसा कि कहा गया है, आपको अपनी प्रकृति को परिभाषित करने की आवश्यकता है executing contextजहां आप awaitकिसी भी चीज़ से पहले किसी कार्य के लिए तैयार हैं ।

बस asyncउस fnघोषणा से पहले रखें जिसमें आपका asyncकार्य निष्पादित होगा।

var start = async function(a, b) { 
  // Your async task will execute with await
  await foo()
  console.log('I will execute after foo get either resolved/rejected')
}

स्पष्टीकरण:

आपके प्रश्न में, आप आयात कर रहे हैं methodजो asynchronousप्रकृति में है और समानांतर में निष्पादित होगा। लेकिन जहाँ आप उस asyncतरीके को अंजाम देने की कोशिश कर रहे हैं, वह अलग है, execution contextजिसे आपको asyncउपयोग करने के लिए परिभाषित करने की आवश्यकता है await

 var helper = require('./helper.js');   
 var start = async function(a,b){
     ....
     const result = await helper.myfunction('test','test');
 }
 exports.start = start;

आश्चर्य है कि हुड के नीचे क्या हो रहा है

await खपत / भविष्य / कार्य-वापसी के तरीके / कार्य और async प्रतीक्षा करने में सक्षम के रूप में एक विधि / कार्य को चिह्नित करता है।

इसके अलावा अगर आप परिचित हैं promises, awaitवास्तव में वादे / संकल्प की एक ही प्रक्रिया कर रहे हैं। वादा की एक श्रृंखला बनाने और आप में अगले कार्य को क्रियान्वित करता हैresolve कॉलबैक ।

अधिक जानकारी के लिए आप एमडीएन डॉक्स का उल्लेख कर सकते हैं ।


यहां तक ​​कि प्रारंभ समारोह में async के साथ मुझे त्रुटि मिल रही है
j.doe

मुझे यकीन नहीं है कि आप कहां चूक रहे हैं और इस त्रुटि को प्राप्त कर रहे हैं, इस त्रुटि को हल करने के लिए ऐसी कोई जटिल व्याख्या नहीं है।
सत्यम पाठक

यह एक उचित जवाब है और वास्तव में अंडरलाइन कारण बताया गया है। मतदान किया।
लाइनर्र

3

वर्तमान में लागू async/ कार्य के अंदर awaitकेवल awaitकीवर्ड का समर्थन करता है asyncअपने startफ़ंक्शन हस्ताक्षर को बदलें ताकि आप awaitअंदर उपयोग कर सकें start

 var start = async function(a, b) {

 }

रुचि रखने वालों के लिए, शीर्ष स्तर awaitका प्रस्ताव वर्तमान में स्टेज 2 में है: https://github.com/tc39/proposal-top-level-await


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

1
हर समारोह जो अविवेक के किसी भी स्तर के माध्यम से एक बाहरी प्रक्रिया चाहिए के परिणामों पर निर्भर है, और चाहिए साथ में परिभाषित किया जा async- बात यह है कि पूरे बिंदु की async
गेरशोम

आप वर्तमान में इसे नोड रिप्लाई --experimental-repl-awaitविकल्प का उपयोग कर सकते हैं ।
लॉज

3

मुझे एक ही समस्या थी और कोड का निम्नलिखित ब्लॉक समान त्रुटि संदेश दे रहा था:

repositories.forEach( repo => {
        const commits = await getCommits(repo);
        displayCommit(commits);
});

समस्या यह है कि विधि getCommits () async थी, लेकिन मैं इसे तर्क रेपो पास कर रहा था जो कि एक प्रॉमिस द्वारा भी निर्मित किया गया था। इसलिए, मुझे इस तरह से async शब्द जोड़ना पड़ा: async (रेपो) और इसने काम करना शुरू कर दिया:

repositories.forEach( async(repo) => {
        const commits = await getCommits(repo);
        displayCommit(commits);
});

0

async / प्रतीक्षा से निपटने का तंत्र है, दो तरीके जो हम कर सकते हैं

functionWhichReturnsPromise()
            .then(result => {
                console.log(result);
            })
            .cathc(err => {
                console.log(result);

            });

या हम पहले इसे पूर्ण रूप से दायर करने के वादे की प्रतीक्षा करने के लिए प्रतीक्षा का उपयोग कर सकते हैं, जिसका अर्थ है कि या तो इसे अस्वीकार या हल किया गया है।

अब अगर हम किसी फ़ंक्शन के अंदर वेट (वादे के पूरा होने का इंतजार ) का उपयोग करना चाहते हैं , तो यह अनिवार्य है कि कंटेनर फ़ंक्शन एक async फ़ंक्शन होना चाहिए क्योंकि हम असंगत रूप से पूरा करने के लिए एक वादे की प्रतीक्षा कर रहे हैं || सही समझें?

async function getRecipesAw(){
            const IDs = await getIds; // returns promise
            const recipe = await getRecipe(IDs[2]); // returns promise
            return recipe; // returning a promise
        }

        getRecipesAw().then(result=>{
            console.log(result);
        }).catch(error=>{
            console.log(error);
        });

-2

"async फ़ंक्शन में प्रतीक्षा केवल मान्य है"

पर क्यों? 'प्रतीक्षा' स्पष्ट रूप से एक सिंक्रोनस कॉल में एक async कॉल को बदल देता है, और इसलिए कॉल करने वाला async (या asyncable) नहीं हो सकता है - कम से कम नहीं, क्योंकि 'कॉल' का इंतजार किया जा रहा है।


1
वास्तव में, इंतजार परिणाम का इंतजार नहीं करता है - यह तुरंत एक वादा वापस करता है। यह वही है जो मैं व्यक्त करने का प्रयास कर रहा था। यदि वास्तव में प्रतीक्षारत प्रतीक्षारत है और फोन करने वाले के लिए नियंत्रण वापस नहीं आया है, तो किसी भी फ़ंक्शन जिसमें एक प्रतीक्षित कीवर्ड शामिल है, का शाब्दिक रूप से async चिह्नित नहीं किया जा सकेगा। लेकिन इसके बजाय, हमारे पास कोई भी फ़ंक्शन है जिसमें प्रतीक्षा शामिल है या एक फ़ंक्शन को कॉल करता है जो अंततः प्रतीक्षा वाले फ़ंक्शन को कॉल करता है जो कि async होना चाहिए। मूल रूप से, यदि आप एक बार भी प्रतीक्षा करते हैं, तो आपके सभी कार्यों को एस्किंक के रूप में चिह्नित किया जाना चाहिए।
रॉडने पी। बारबाती

-5

हां, वेट / एसिंक्स एक बेहतरीन अवधारणा थी, लेकिन कार्यान्वयन पूरी तरह से टूट गया है।

जो भी कारण के लिए, प्रतीक्षित कीवर्ड को इस तरह से लागू किया गया है कि इसका उपयोग केवल एक async विधि के भीतर किया जा सकता है। यह वास्तव में एक बग है, हालांकि आप इसे कहीं भी, लेकिन यहीं संदर्भित नहीं देखेंगे। इस बग के लिए इंतजार प्रतीक्षित कीवर्ड को लागू करने के लिए होगा, जैसे कि इसे केवल कॉल करने के लिए एक async फ़ंक्शन का उपयोग किया जा सकता है, भले ही कॉलिंग फ़ंक्शन समकालिक या अतुल्यकालिक हो।

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

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

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

तो, जावास्क्रिप्ट और ECMAScript के डेवलपर्स के लिए - कृपया इस प्रकार के रूप में प्रतीक्षा / async कार्यान्वयन को ठीक करें ...

  • प्रतीक्षा का उपयोग केवल ASync फ़ंक्शन को कॉल करने के लिए किया जा सकता है।
  • प्रतीक्षा किसी भी प्रकार के फ़ंक्शन, सिंक्रोनस या एसिंक्रोनस में दिखाई दे सकती है।
  • त्रुटि संदेश को "प्रतीक्षा में केवल async फ़ंक्शन में मान्य है" से बदलें "प्रतीक्षा करने के लिए केवल async फ़ंक्शन को कॉल करने के लिए उपयोग किया जा सकता है"।

आप चाहें तो इसे बग कह सकते हैं, लेकिन मैं असहमत हूं। कोड जैसी कोई चीज नहीं है जो "रोकती है" - बल्कि, ऐसा कोड है जो कुछ बाहरी प्रक्रिया (आमतौर पर io) के परिणामों के बिना पूरा नहीं हो सकता है। इस तरह के कोड को "अतुल्यकालिक" कहा जाना चाहिए क्योंकि जावास्क्रिप्ट वीएम के विपरीत कई बाहरी प्रक्रियाएं एक ही समय (गैर-समकालिक) में चलने में सक्षम होनी चाहिए जो कि एकल-थ्रेडेड है। यदि आपके पास कई कार्य हैं जिन्हें करने की आवश्यकता asyncहै तो इस तथ्य को दर्शाता है कि आपके कई कार्यों को बाहरी प्रक्रियाओं के परिणामों की आवश्यकता होती है। यह मेरी राय में पूरी तरह से विहित है।
गर्सहोम

यह awaitकेवल फ़ंक्शन कॉल के साथ प्रयोग करने योग्य होने के लिए प्रतिबंधित करने के एक भयानक दोष का उल्लेख करने योग्य है: एक एकल बाहरी प्रक्रिया के लिए, जावास्क्रिप्ट कोड में केवल एक बिंदु को अधिसूचित किया जा सकता है जब यह प्रक्रिया पूरी हो जाती है। उदाहरण के लिए यदि किसी फ़ाइल की सामग्री की आवश्यकता 3 स्वतंत्र उद्देश्यों के लिए है, तो प्रत्येक उद्देश्य को स्वतंत्र रूप से करने की आवश्यकता होगी let content = await readTheFile();- ऐसा इसलिए है क्योंकि "फ़ाइल की सामग्री का वादा" प्रतीक्षा नहीं की जा सकती है, केवल "फ़ाइल को पढ़ने और एक बार फिर से शुरू करने का कार्य" पढ़ें "।
गर्सहोम

ठीक है, चलो इसे उस कोड को नहीं कहते हैं जो रुकता है, या कोड जो पूरा नहीं हो सकता है, लेकिन अवरुद्ध प्रतीक्षा के बारे में कैसे। यहाँ रगड़ है - वह फ़ंक्शन जो प्रतीक्षा को अवरुद्ध करता है या जो पूरा नहीं कर सकता है वह फ़ंक्शन है जिसमें प्रतीक्षा कीवर्ड शामिल है। यह async फ़ंक्शन नहीं है जिसे प्रतीक्षा कीवर्ड के साथ बुलाया जा रहा है। इसलिए, प्रतीक्षित कीवर्ड वाले फ़ंक्शन को निश्चित रूप से async के रूप में चिह्नित नहीं करना चाहिए - यह प्रतीक्षा को अवरुद्ध करता है, जो एसिंक्रोनस के विपरीत है।
रॉडने पी। बारबाती

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

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