অপেক্ষা কেবলমাত্র অ্যাসিঙ্ক ফাংশনেই বৈধ


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;

আমি একটি ত্রুটি পেয়েছি

"অপেক্ষা কেবল অ্যাসিঙ্ক ফাংশনেই বৈধ"

সমস্যা কি?


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সঠিক এবং গুরুত্বপূর্ণ: (চেষ্টা করুন / ধরুন)

"প্রতীক্ষার প্রতীক্ষায়" নিয়ে পারফরম্যান্স নিয়ে উদ্বেগ রয়েছে?


তবে এটি কাজ করছে না, আমি আমার কোড আপডেট করেছি। আমি এখনও একই ত্রুটি
পেয়েছি

@ j.doe আমি একটি স্নিপেট যুক্ত করেছি
গ্রেগরি

2
ধন্যবাদ, আমি আমার সমস্যাটি পেয়েছি। আমি কলব্যাকের ভিতরে এটি করার চেষ্টা করছিলাম তা হল () ফাংশন। সমাধানটি ছিল: কনস্টার্ট স্টার্ট = অ্যাসিঙ্ক ফাংশন (ক, খ) {টাস্ক.জেট (বিকল্পগুলি, অ্যাসিঙ্ক ফাংশন (ত্রুটি, ফলাফল 1) {কনসাল্ট ফলাফল = মাইফ্যাংশনের জন্য অপেক্ষা করুন ('পরীক্ষা', 'পরীক্ষা');
j.doe

নোড একক থ্রেডযুক্ত বিবেচনা করে। এটি প্রতি মিনিটে অনুরোধ হ্রাস করে না এবং পূর্ণ পূরণের অনুরোধগুলির মধ্যে বিলম্বও বাড়িয়ে তোলে।
habষভ ধীমান

1
এটি উল্লেখযোগ্য যে "" সত্য "উদাহরণে, startএকটি asyncফাংশন হিসাবে ঘোষণা করার প্রয়োজন নেই (যদিও কিছু আরও স্পষ্টভাবে প্রকাশের জন্য এটি করা বেছে নেবে)
গেরশোম

11

যখন আমি এই ত্রুটিটি পেয়েছি তখন দেখা গেল আমার "অ্যাসিঙ্ক" ফাংশনের অভ্যন্তরে মানচিত্রের ফাংশনে আমার কল ছিল, সুতরাং এই ত্রুটি বার্তাটি আসলে "অ্যাসিঙ্ক" হিসাবে চিহ্নিত না হয়ে মানচিত্রের ফাংশনটির কথা উল্লেখ করেছিল। আমি মানচিত্রের ফাংশনটি থেকে "অপেক্ষা" করলাম এবং প্রত্যাশিত আচরণ পাওয়ার অন্য কোনও উপায় নিয়ে এসে এই সমস্যাটি ঘটিয়েছি।

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

2
এটা আমার জন্য সমস্যা ছিল। আমি মানচিত্রের ফাংশনটি একটি ফর লুপের সাথে প্রতিস্থাপন করেছি, যা আমার পক্ষে সহজ সমাধান ছিল। তবে এই কোডটি আপনার কোডের উপর নির্ভর করে আপনার জন্য কাজ না করে।
টমাস

6
এফওয়াইআই আপনি এটিও করতে পারেনsomeArray.map(async (someVariable) => { return await someFunction(someVariable)})
পিটিএম

1
awaitআপনার কোডে, বিভ্রান্তিকর, কারণ Array.mapএকটি অ্যাসিঙ্ক্রোনাস ফাংশন হিসাবে ফাংশন হ্যান্ডেল করা হবে না। পুরোপুরি পরিষ্কার হওয়ার জন্য, mapফাংশনটি শেষ হওয়ার পরে , someFunctionসমস্তগুলি মুলতুবি থাকবে। আপনি যদি সত্যিই ফাংশনগুলি শেষ করতে অপেক্ষা করতে চান তবে আপনাকে লিখতে হবে: await Promise.all(someArray.map(someVariable => someFunction(someVariable)))বা await Promise.all(someArray.map(someFunction)))
গ্রেগরি নিউইট

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কলব্যাকে আপনাকে পরবর্তী কাজটি সম্পাদন করে ।

আরও তথ্যের জন্য আপনি MDN ডকস দেখতে পারেন ।



আপনি কোথায় অনুপস্থিত এবং এই ত্রুটিটি পেয়েছেন তা আমি নিশ্চিত নই, এই ত্রুটিটি সমাধান করার জন্য এরকম জটিল ব্যাখ্যা নেই।
সত্যম পাঠক

এটি একটি সঠিক উত্তর এবং প্রকৃতপক্ষে আন্ডারলাইন কারণটি ব্যাখ্যা করেছে explained ভোট দিয়েছেন।
লাইনহর

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
দুর্ভাগ্যক্রমে, এর মূল অর্থ যা হ'ল এটি হ'ল আপনাকে আপনার পুরো কোড বেস জুড়ে আপনার সমস্ত ফাংশনকে অ্যাসিঙ্ক করতে হবে। কারণ আপনি যদি অপেক্ষা করতে চান, আপনার অবশ্যই এটি একটি অ্যাসিঙ্ক ফাংশনে করা উচিত, যার অর্থ আপনাকে ফাংশনটিতে কল করার জন্য সেই ফাংশনের প্রতিক্রিয়ার জন্য অপেক্ষা করতে হবে - আবার, এর অর্থ হ'ল আপনার সমস্ত ফাংশন অ্যাসিঙ্ক হওয়া দরকার। আমার কাছে এর অর্থ হ'ল অপেক্ষারত এসিঙ্ক ব্যবহারের জন্য প্রস্তুত নয়। বর্তমান ফাংশনটি সিনক্রোনাস বা অ্যাসিঙ্ক্রোনাস কিনা তা নির্বিশেষে আপনি যখন অ্যাসিঙ্ক পদ্ধতিটি কল করার জন্য অপেক্ষা করতে পারেন তখন তা মূল সময়ের জন্য প্রস্তুত থাকবে।
রডনি পি বারবতি

1
প্রতিটি ফাংশন যা অপ্রত্যক্ষ্যতার কোনো স্তরের মাধ্যমে একটি বহিস্থিত প্রক্রিয়া আবশ্যক ফলাফল উপর নির্ভরশীল, এবং উচিত সঙ্গে সংজ্ঞায়িত করা async- যে সমগ্র বিন্দু এর async
Gershom

আপনি বর্তমানে --experimental-repl-awaitবিকল্পটি ব্যবহার করে নোড Repl এ এটি ব্যবহার করতে পারেন ।
লডজ

3

আমার একই সমস্যা ছিল এবং নিম্নলিখিত কোডের ব্লকটি একই ত্রুটি বার্তা দিচ্ছিল:

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

সমস্যাটি হ'ল পদ্ধতিটি getCommits () 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 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

"অপেক্ষা কেবল অ্যাসিঙ্ক ফাংশনেই বৈধ"

কিন্তু কেন? 'অপেক্ষা' স্পষ্টরূপে একটি অ্যাসিঙ্ক কলকে একটি সিঙ্ক্রোনাস কলগুলিতে রূপান্তরিত করে, এবং তাই কলার 'অপেক্ষার' সময়ে কল করার কারণে নয়, অন্তত: অ্যাসিঙ্ক (বা অ্যাসিঙ্কেবল) হতে পারে না।


1
আসলে, অপেক্ষা অপেক্ষা ফলাফলের জন্য অপেক্ষা করে না - এটি অবিলম্বে একটি প্রতিশ্রুতি দেয় returns এটিই আমি জানাতে চাইছিলাম। যদি অপেক্ষা প্রকৃতপক্ষে অপেক্ষা করা হয় এবং কলারের কাছে নিয়ন্ত্রণ ফিরে না আসে, তবে অপেক্ষার কীওয়ার্ড থাকা যে কোনও ক্রিয়াকলাপটি আক্ষরিক অর্থে অ্যাসিঙ্ক হিসাবে চিহ্নিত হতে সক্ষম হবে না। তবে এর পরিবর্তে, আমাদের কোনও ফাংশন রয়েছে যার মধ্যে অপেক্ষা বা একটি ফাংশন কল করে যা অবশেষে প্রত্যাশিত একটি ফাংশনকে কল করে তা অবশ্যই async হওয়া উচিত। মূলত, আপনি যদি একবার কল করেও ডাকেন - আপনার সমস্ত ফাংশন অবশ্যই async হিসাবে চিহ্নিত করা উচিত।
রডনি পি বারবতি

-5

হ্যাঁ, অপেক্ষা / অ্যাসিঙ্কটি একটি দুর্দান্ত ধারণা ছিল, তবে বাস্তবায়ন সম্পূর্ণরূপে ভেঙে গেছে।

যে কারণেই হোক না কেন, অপেক্ষার কীওয়ার্ডটি এমনভাবে প্রয়োগ করা হয়েছে যে এটি কেবল একটি অ্যাসিঙ্ক পদ্ধতির মধ্যেই ব্যবহার করা যেতে পারে। এটি আসলে একটি বাগ, যদিও আপনি এটিকে কোথাও কোথাও উল্লেখ করা দেখতে পাবেন না তবে ঠিক এখানে। এই ত্রুটির সমাধানটি হ'ল অপেক্ষার মূলশব্দটি কার্যকর করা যেমন কলিং ফাংশনটি নিজেই সিঙ্ক্রোনাস বা অ্যাসিনক্রোনাস হয় তা নির্বিশেষে এটি কেবলমাত্র একটি অ্যাসিঙ্ক ফাংশন কল করতে ব্যবহার করা যেতে পারে।

এই বাগের কারণে, আপনি যদি নিজের কোডের কোথাও একটি আসল অ্যাসিঙ্ক্রোনাস ফাংশন কল করতে অপেক্ষা করেন, তবে আপনার সমস্ত ফাংশন অবশ্যই অ্যাসিঙ্ক হিসাবে চিহ্নিত করা উচিত এবং আপনার সমস্ত ফাংশন কল অপেক্ষা করতে হবে।

এর মূল অর্থ হল যে আপনাকে অবশ্যই আপনার সম্পূর্ণ প্রয়োগের সমস্ত ফাংশনে প্রতিশ্রুতিগুলির ওভারহেড যুক্ত করতে হবে, যার বেশিরভাগই অ্যাসিঙ্ক্রোনাস হবে না এবং কখনও হবে না।

আপনি যদি সত্যিই এটির বিষয়ে চিন্তা করেন তবে কোনও ফাংশনে অপেক্ষা করার জন্য ওয়েভেট কীওয়ার্ডটি ASYNC না হওয়ার জন্য প্রয়োজনীয় ফাংশনটি প্রয়োজন - এটি কারণ হ'ল অপেক্ষার কীওয়ার্ডটি ফাংশনে প্রসেসিংকে বিরতি দিতে চলেছে যেখানে অপেক্ষার কীওয়ার্ডটি পাওয়া যায়। যদি সেই ফাংশনে প্রসেসিংকে বিরতি দেওয়া হয় তবে তা অবশ্যই সংশ্লেষীয় নয়।

সুতরাং, জাভাস্ক্রিপ্ট এবং ECMAScript এর বিকাশকারীদের - দয়া করে অপেক্ষা / অ্যাসিঙ্ক বাস্তবায়ন নীচের হিসাবে ঠিক করুন ...

  • অপেক্ষা কেবলমাত্র এসিঙ্ক ফাংশনগুলিতে কল করতে ব্যবহৃত হতে পারে।
  • অপেক্ষারত কোনও ধরণের ক্রিয়াকলাপে, সিঙ্ক্রোনাস বা অ্যাসিনক্রোনাসে উপস্থিত হতে পারে।
  • "প্রতীক্ষা কেবলমাত্র async ফাংশনে বৈধ" থেকে "অপেক্ষা করুন কেবলমাত্র async ফাংশনগুলি কল করতে ব্যবহৃত হতে পারে" তে ত্রুটি বার্তাটি পরিবর্তন করুন।

আপনি চাইলে এটিকে বাগ বলতে পারেন, তবে আমি একমত নই। কোড বলে কিছু নেই যা "বিরতি দেয়" - বরং, এমন কোড রয়েছে যা কিছু বাহ্যিক প্রক্রিয়া (সাধারণত আইও) ফলাফল ছাড়াই সম্পূর্ণ করতে পারে না। জাভাস্ক্রিপ্ট ভিএম যা একক থ্রেডযুক্ত তার বিপরীতে অনেকগুলি বহিরাগত প্রক্রিয়া একই সাথে চালাতে সক্ষম হওয়া উচিত (একইসাথে অ-সংশ্লেষে) একই ধরণের কোডকে "অবিচ্ছিন্ন" বলা উচিত। আপনার যদি অনেকগুলি ক্রিয়াকলাপ থাকে যা রিফ্যাক্টর করা দরকার asyncতা প্রতিফলিত করে যে আপনার অনেক ফাংশনের জন্য বাহ্যিক প্রক্রিয়ার ফলাফল প্রয়োজন। এটা আমার মতে সম্পূর্ণরূপে প্রমিত।
গেরশম

এটি awaitকেবলমাত্র ফাংশন কলগুলির সাথে ব্যবহারযোগ্য হতে পারে তা সীমাবদ্ধ করার একটি ভয়ানক অপূর্ণতা উল্লেখ করার মতো: একটি একক বহিরাগত প্রক্রিয়ার জন্য, যখন প্রক্রিয়াটি সম্পূর্ণ হয় জাভাস্ক্রিপ্ট কোডে কেবলমাত্র একটি বিন্দু অবহিত হতে পারে। উদাহরণস্বরূপ, যদি কোনও ফাইলের বিষয়বস্তু 3 টি স্বতন্ত্র উদ্দেশ্যে প্রয়োজন হয় তবে প্রতিটি উদ্দেশ্য স্বাধীনভাবে করা উচিত let content = await readTheFile();- এটি কারণ "ফাইলটির বিষয়বস্তুর প্রতিশ্রুতি" অপেক্ষা করা যায় না, কেবল "ফাইলটি পড়া এবং একবার হয়ে যাওয়ার পরে এটি পুনরায় শুরু করার কাজ act পড়া "।
গেরশম

ঠিক আছে, আসুন আমরা এটিকে বিরতিযুক্ত কোড বা কোডটি না বলে যা শেষ করতে পারে না, তবে কীভাবে অবরুদ্ধ অপেক্ষার বিষয়ে। এখানে ঘষা - যে ফাংশনটি অপেক্ষারত অবরুদ্ধ বা সম্পূর্ণ করতে পারে না তা হ'ল সেই ফাংশনটিতে অপেক্ষা করা কীওয়ার্ড রয়েছে। এটি অপেক্ষার কীওয়ার্ড সহ কল ​​করা হচ্ছে এমন async ফাংশন নয়। সুতরাং, অপেক্ষার কীওয়ার্ড সহ ফাংশনটি অবশ্যই অ্যাসিঙ্ক হিসাবে চিহ্নিত করা উচিত নয় - এটি অপেক্ষারত অবরুদ্ধ, যা অ্যাসিঙ্ক্রোনাসের বিপরীত।
রডনি পি বারবতি

এটিকে পুরোপুরি পরিষ্কার করার জন্য, নিম্নলিখিতটি বিবেচনা করুন - প্রত্যাশার উদ্দেশ্য হ'ল অ্যাসিনক্রোনাস ফাংশনগুলি সহজলভ্য করে এটি সিঙ্ক্রোনাস হিসাবে উপস্থিত হওয়া (যেমন এটি আমাকে একটি নির্দিষ্ট ক্রমে জিনিসগুলি করতে দেয়)। অ্যাসিঙ্ক হওয়ার অপেক্ষায় থাকা ক্রিয়াকলাপটি বাধ্যতামূলকভাবে সম্পূর্ণ মিথ্যাচিকেন্দ্র - আপনি অপেক্ষা করতেন যাতে এটি সিনক্রোনাস হয়। একটি প্রতীক্ষিত সমন্বিত একটি ফাংশন একেবারে, প্রতিটি অনুমেয় পদ্ধতিতে, একটি অ্যাসিঙ্ক ফাংশন নয় !!!
রডনি পি বারবতি

1
@ জারশম - এটি যুক্তিসঙ্গত মনে হচ্ছে। ধন্যবাদ!
রডনি পি বারবতি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.