forEach/map और async साथ-साथ नहीं चलते हैं

May 07 2023
कई बार, हम अक्सर forEach और map फ़ंक्शंस के साथ async फ़ंक्शंस पास करते हैं। उदाहरण के लिए: परिणाम: 1 से सभी संख्याएँ।
हैडर

कई बार, हम अक्सर forEach और map फ़ंक्शंस के साथ async फ़ंक्शंस पास करते हैं।

पूर्व के लिए:

[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));

परिणाम: 1..5 से सभी संख्याएँ एक के बाद एक छपती हैं लेकिनप्रत्येक पंक्ति के छपने के बाद 1 सेकंड का अंतराल नहीं होता है।

ऐसा क्यूँ होता है?

इस जावास्क्रिप्ट फ़ंक्शन को देखें:

async function doubleOf(n) {
  return n*2;
}

परिणाम: यह वास्तव में एक वादा लौटा रहा है जो एक संख्या को हल करता है।

यदि हम इस फ़ंक्शन के समतुल्य टाइपस्क्रिप्ट को सख्त प्रकारों के साथ लिखते हैं, तो यह चीजों को स्पष्ट कर देगा।

निम्नलिखित कोड संकलित नहीं होगा :

async function doubleOf(n: number): number {
  return n*2;
}

सही संस्करण होगा:

async function doubleOf(n: number): Promise<number> {
  return n*2;
}

async-wait द्वारा प्रदान की गई सिंटैक्टिक चीनी से मूर्ख मत बनो। यदि हम async का उपयोग किए बिना शुद्ध वादे लिखते हैं, तो उपरोक्त कार्य इस तरह दिखेगा:

function doubleOf(n) {
  return new Promise((resolve) => resolve(n*2));
}

function doubleOf(n: number): Promise<number> {
  return new Promise((resolve) => resolve(n*2));
}

async फ़ंक्शन वादों को लौटाता है न कि मूल्यों को
  1. हमारे पास doubleOfऐसा कार्य है जो एक संख्या लेता है और एक संख्या देता है। सादा पुराना जावास्क्रिप्ट।
  2. हमारे पास doubleOfOldWayऐसा कार्य है जो एक संख्या लेता है और एक वादा देता है जो एक संख्या को हल करता है।
  3. हमारे पास doubleOfNewWayएक एसिंक्स फ़ंक्शन है जो एक नंबर लेता है और ऐसा लगता है जैसे यह एक नंबर देता है, लेकिन यह वास्तव में एक वादा देता है जो doubleOfOldWayफ़ंक्शन की तरह एक संख्या को हल करता है।
  4. doubleOfOldWayऔर doubleOfNewWayकार्य बिल्कुल समान हैं।
  5. doubleOfOldWayऔर इसलिए, जब हम द्वारा लौटाए गए मूल्यों और कार्यों पर एक गुणा ऑपरेशन को निष्पादित करने का प्रयास करते हैं doubleOfNewWay, तो परिणाम था NaN, क्योंकि हम कई वादे नहीं कर सकते (जाहिर है!)
  6. गुणा करना doubleOfOldWayऔर doubleOfNewWay:

तो वापस हमारे प्रारंभिक उदाहरण पर:

[1,2,3,4,5].forEach(async (n) => setTimeout(console.log(n), 1000));

इस forEach फ़ंक्शन से हम जो उम्मीद करते हैं उसे लागू करने का सबसे सही तरीका एक सरल for लूप का उपयोग करना है:

for(const number of [1,2,3,4,5]) {
    console.log(number);
    await new Promise(resolve => setTimeout(resolve, 1000)); // Sleep for "atleast" 1 second
}

[1,2,3,4,5].map(async (n) => n*2);

(5) [Promise, Promise, Promise, Promise, Promise]
0: Promise {<fulfilled>: 2}
1: Promise {<fulfilled>: 4}
2: Promise {<fulfilled>: 6}
3: Promise {<fulfilled>: 8}
4: Promise {<fulfilled>: 10}

प्रत्येक संख्या के दोगुने की सूची प्राप्त करने के लिए, हम क्या कर सकते हैं:

await Promise.all([1,2,3,4,5].map(async (n) => n*2));

[2, 4, 6, 8, 10]