खोज…


परिचय

एसिंक्रोनस कार्यों को इनलाइन व्यक्त करने के लिए वादों और जनरेटर के शीर्ष पर async और await । यह अतुल्यकालिक या कॉलबैक कोड को बनाए रखने के लिए बहुत आसान बनाता है।

async कीवर्ड वाले कार्य एक Promise वापस करते हैं, और उस सिंटैक्स के साथ कॉल किया जा सकता है।

एक के अंदर async function await कीवर्ड किसी भी लागू किया जा सकता Promise , और के बाद समारोह शरीर के सभी कारण होगा await वादा निराकरण के बाद निष्पादित किया जाना है।

वाक्य - विन्यास

  • async फ़ंक्शन फू () {
    ...
    asyncCall का इंतजार करें ()
    }
  • async फ़ंक्शन () {...}
  • async () => {...}
  • (async () => {
    const data = asyncCall का इंतजार करें ()
    कंसोल.लॉग (डेटा)}) ()

टिप्पणियों

Async फ़ंक्शंस वादों और जनरेटरों पर एक सिंटैक्टिक शुगर है। वे आपके कोड को अधिक पठनीय, बनाए रखने में आसान बनाते हैं, त्रुटियों को कम करने और इंडेंटेशन के कम स्तरों के साथ आसान बनाते हैं।

परिचय

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

नोट: Async फ़ंक्शंस ECMAScript 2017 मानक में शामिल किए जाने के लिए ट्रैक पर एक स्टेज 4 ("समाप्त") प्रस्ताव है

उदाहरण के लिए, वादा-आधारित Fetch API का उपयोग करना:

async function getJSON(url) {
    try {
        const response = await fetch(url);
        return await response.json();
    }
    catch (err) {
        // Rejections in the promise will get thrown here
        console.error(err.message);
    }
}

एक async फ़ंक्शन हमेशा एक वादा खुद लौटाता है, इसलिए आप इसे अन्य अतुल्यकालिक कार्यों में उपयोग कर सकते हैं।

एरो फंक्शन स्टाइल

const getJSON = async url => {
    const response = await fetch(url);
    return await response.json();
}

कम इंडेंटेशन

वादों के साथ:

function doTheThing() {
    return doOneThing()
        .then(doAnother)
        .then(doSomeMore)
        .catch(handleErrors)
}

Async फ़ंक्शन के साथ:

async function doTheThing() {
    try {
        const one = await doOneThing();
        const another = await doAnother(one);
        return await doSomeMore(another);
    } catch (err) {
        handleErrors(err);
    }
}

ध्यान दें कि वापसी नीचे कैसे है, और शीर्ष पर नहीं है, और आप भाषा के मूल त्रुटि-हैंडलिंग मैकेनिक्स ( try/catch ) का उपयोग करते हैं।

प्रतीक्षा और ऑपरेटर पूर्वता

आपको await कीवर्ड का उपयोग करते समय ऑपरेटर की पूर्वता को ध्यान में रखना होगा।

कल्पना कीजिए कि हमारे पास एक एसिंक्रोनस फ़ंक्शन है जो एक अन्य एसिंक्रोनस फ़ंक्शन को कॉल करता है, getUnicorn() जो एक वादा करता है जो क्लास Unicorn एक उदाहरण के लिए हल करता है। अब हम उस वर्ग की getSize() पद्धति का उपयोग करके गेंडा का आकार प्राप्त करना चाहते हैं।

निम्नलिखित कोड देखें:

async function myAsyncFunction() {
    await getUnicorn().getSize();
}

पहली नजर में यह वैध लगता है, लेकिन ऐसा नहीं है। ऑपरेटर पूर्वता के कारण, यह निम्नलिखित के बराबर है:

async function myAsyncFunction() {
    await (getUnicorn().getSize());
}

यहाँ हम वादा वस्तु के getSize() विधि को कॉल करने का प्रयास करते हैं, जो कि हम नहीं चाहते हैं।

इसके बजाय, हमें यह इंगित करने के लिए कोष्ठक का उपयोग करना चाहिए कि हम पहले गेंडा की प्रतीक्षा करना चाहते हैं, और फिर getSize() परिणाम की विधि को कॉल करें:

async function asyncFunction() {
    (await getUnicorn()).getSize();
}

बेशक। पिछला संस्करण कुछ मामलों में मान्य हो सकता है, उदाहरण के लिए, यदि getUnicorn() फ़ंक्शन सिंक्रोनस था, लेकिन getSize() विधि अतुल्यकालिक थी।

वादा के मुकाबले Async फ़ंक्शन

async फ़ंक्शन Promise प्रकार को प्रतिस्थापित नहीं Promise ; वे ऐसे भाषा कीवर्ड जोड़ते हैं जो कॉल करने के वादे को आसान बनाते हैं। वे विनिमेय हैं:

async function doAsyncThing() { ... }

function doPromiseThing(input) { return new Promise((r, x) => ...); }

// Call with promise syntax
doAsyncThing()
    .then(a => doPromiseThing(a))
    .then(b => ...)
    .catch(ex => ...);

// Call with await syntax
try {
    const a = await doAsyncThing();
    const b = await doPromiseThing(a);
    ...
}
catch(ex) { ... }

कोई भी फ़ंक्शन जो वादों की श्रृंखला का उपयोग await का उपयोग करके फिर से लिखा जा सकता है:

function newUnicorn() {
  return fetch('unicorn.json')                     // fetch unicorn.json from server
  .then(responseCurrent => responseCurrent.json()) // parse the response as JSON
  .then(unicorn =>
    fetch('new/unicorn', {                         // send a request to 'new/unicorn' 
        method: 'post',                            // using the POST method
        body: JSON.stringify({unicorn})            // pass the unicorn to the request body
    })
  )
  .then(responseNew => responseNew.json())
  .then(json => json.success)                      // return success property of response
  .catch(err => console.log('Error creating unicorn:', err));
 }

समारोह का उपयोग कर लिखा जा सकता है async / await के रूप में इस प्रकार है:

async function newUnicorn() {
  try {
    const responseCurrent = await fetch('unicorn.json'); // fetch unicorn.json from server
    const unicorn = await responseCurrent.json();        // parse the response as JSON
    const responseNew = await fetch('new/unicorn', {     // send a request to 'new/unicorn'
      method: 'post',                                    // using the POST method
      body: JSON.stringify({unicorn})                    // pass the unicorn to the request body
    });
    const json = await responseNew.json();
    return json.success                                  // return success property of response
  } catch (err) {
    console.log('Error creating unicorn:', err);
  }
}

newUnicorn() का यह async संस्करण एक Promise वापस करने के लिए प्रकट होता है, लेकिन वास्तव में कई await कीवर्ड थे। प्रत्येक ने एक Promise वापस किया, इसलिए वास्तव में हमारे पास श्रृंखला के बजाय वादों का एक संग्रह था।

वास्तव में हम एक के रूप में यह सोच सकते हैं function* प्रत्येक के साथ, जनरेटर await एक किया जा रहा yield new Promise । हालांकि, प्रत्येक वादे के परिणाम को फ़ंक्शन जारी रखने के लिए अगले की आवश्यकता होती है। यही कारण है कि फ़ंक्शन पर अतिरिक्त कीवर्ड async की आवश्यकता होती है (साथ ही वादों को कॉल करते समय await कीवर्ड) क्योंकि यह जावास्क्रिप्ट को बताता है कि स्वचालित रूप से इस पुनरावृत्ति के लिए एक पर्यवेक्षक बनाता है। async function newUnicorn() द्वारा लौटाया गया Promise जब यह पुनरावृत्ति पूर्ण हो जाता है।

व्यावहारिक रूप से, आपको उस पर विचार करने की आवश्यकता नहीं है; await छुपाता है वादा और async जनरेटर पुनरावृत्ति छुपाता है।

आप async फ़ंक्शंस को कॉल कर सकते हैं जैसे कि वे वादे थे, और किसी भी वादे या किसी भी async फ़ंक्शन का await । आपको async फ़ंक्शन की await करने की आवश्यकता नहीं है, जैसे आप एक .then() बिना एक वादे को निष्पादित कर सकते हैं।

यदि आप उस कोड को तुरंत निष्पादित करना चाहते हैं, तो आप एक async IIFE का उपयोग भी कर सकते हैं:

(async () => {
  await makeCoffee()
  console.log('coffee is ready!')
})()

Async प्रतीक्षा के साथ लूपिंग

लूप में async प्रतीक्षा का उपयोग करते समय, आप इन समस्याओं में से कुछ का सामना कर सकते हैं।

यदि आप अभी forEach अंदर forEach का उपयोग करने का प्रयास करते हैं, तो यह एक Unexpected token त्रुटि को फेंक देगा।

(async() => {
 data = [1, 2, 3, 4, 5];
 data.forEach(e => {
   const i = await somePromiseFn(e);
   console.log(i);
 });
})();

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

उदाहरण:

(async() => {
  data = [1, 2, 3, 4, 5];
  data.forEach(async(e) => {
    const i = await somePromiseFn(e);
    console.log(i);
  });
  console.log('this will print first');
})();

ऐसा इसलिए होता है क्योंकि कॉलबैक async फ़ंक्शन केवल स्वयं को रोक सकता है, न कि पैरेंट async फ़ंक्शन।

आप एक asyncForEach फ़ंक्शन लिख सकते हैं जो एक वादा लौटाता है और फिर आप await asyncForEach(async (e) => await somePromiseFn(e), data ) कर सकते हैं await asyncForEach(async (e) => await somePromiseFn(e), data ) मूल रूप से आप एक वादा वापस करते हैं जो सभी कॉलबैक के इंतजार और किए जाने पर हल होता है। लेकिन ऐसा करने के बेहतर तरीके हैं, और वह सिर्फ एक लूप का उपयोग करना है।

आप लूप के लिए या for/while लूप for-of उपयोग कर सकते हैं, यह वास्तव में कोई फर्क नहीं पड़ता कि आप कौन सा चुनते हैं।

(async() => {
  data = [1, 2, 3, 4, 5];
  for (let e of data) {
    const i = await somePromiseFn(e);
    console.log(i);
  }
  console.log('this will print last');
})();

लेकिन एक और कैच है। यह समाधान प्रत्येक कॉल के लिए प्रतीक्षा करेगा जब कोई अगले से पहले पुनरावृत्ति करने से पहले somePromiseFn पर कॉल करेगा।
यह बहुत अच्छा है कि आप वास्तव में चाहते हैं, तो आपके somePromiseFn आमंत्रण क्रम में निष्पादित किया जाना है लेकिन यदि आप उन्हें समवर्ती चलाना चाहते हैं, तो आप की आवश्यकता होगी await पर Promise.all

(async() => {
 data = [1, 2, 3, 4, 5];
 const p = await Promise.all(data.map(async(e) => await somePromiseFn(e)));
 console.log(...p);
})();

Promise.all अपने एकमात्र पैरामीटर के रूप में वादों की एक सरणी प्राप्त करता है और एक वादा लौटाता है। जब सरणी में सभी वादों का समाधान हो जाता है, तो लौटा हुआ वादा भी हल हो जाता है। हम उस वादे का await करते हैं और जब यह हल हो जाता है तो हमारे सभी मूल्य उपलब्ध होते हैं।

उपरोक्त उदाहरण पूरी तरह से चलने योग्य हैं। somePromiseFn फ़ंक्शन को टाइमआउट के साथ एक async इको फ़ंक्शन के रूप में बनाया जा सकता है। आप कम से कम stage-3 पूर्व निर्धारित और आउटपुट को देखने के साथ बेबल-उत्तर में उदाहरणों को आज़मा सकते हैं।

function somePromiseFn(n) {
 return new Promise((res, rej) => {
   setTimeout(() => res(n), 250);
 });
}

साथ ही साथ एसिंक्रोनस (समानांतर) ऑपरेशन

अक्सर आप समानांतर में अतुल्यकालिक संचालन करना चाहेंगे। वहाँ प्रत्यक्ष सिंटैक्स में इस का समर्थन करता है async / await प्रस्ताव, लेकिन जब से await एक वादा के लिए इंतजार करेंगे, तो आप में एक साथ कई वादे लपेट कर सकते हैं Promise.all उनके लिए प्रतीक्षा करने के लिए:

// Not in parallel

async function getFriendPosts(user) {
    friendIds = await db.get("friends", {user}, {id: 1});
    friendPosts = [];
    for (let id in friendIds) {
        friendPosts = friendPosts.concat( await db.get("posts", {user: id}) );
    }
    // etc.
}

यह प्रत्येक मित्र के पदों को क्रमबद्ध रूप से प्राप्त करने के लिए प्रत्येक क्वेरी करेगा, लेकिन उन्हें एक साथ किया जा सकता है:

// In parallel

async function getFriendPosts(user) {
    friendIds = await.db.get("friends", {user}, {id: 1});
    friendPosts = await Promise.all( friendIds.map(id => 
      db.get("posts", {user: id})
    );
    // etc.
}

यह वादों की एक सरणी बनाने के लिए आईडी की सूची पर लूप करेगा। await होगा सभी वादे पूरे होने का इंतजार Promise.all उन्हें एक ही वादे में जोड़ती है, लेकिन वे समानांतर में किए जाते हैं।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow