forEach/map और async साथ-साथ नहीं चलते हैं
कई बार, हम अक्सर 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));
}
- हमारे पास
doubleOf
ऐसा कार्य है जो एक संख्या लेता है और एक संख्या देता है। सादा पुराना जावास्क्रिप्ट। - हमारे पास
doubleOfOldWay
ऐसा कार्य है जो एक संख्या लेता है और एक वादा देता है जो एक संख्या को हल करता है। - हमारे पास
doubleOfNewWay
एक एसिंक्स फ़ंक्शन है जो एक नंबर लेता है और ऐसा लगता है जैसे यह एक नंबर देता है, लेकिन यह वास्तव में एक वादा देता है जोdoubleOfOldWay
फ़ंक्शन की तरह एक संख्या को हल करता है। doubleOfOldWay
औरdoubleOfNewWay
कार्य बिल्कुल समान हैं।doubleOfOldWay
और इसलिए, जब हम द्वारा लौटाए गए मूल्यों और कार्यों पर एक गुणा ऑपरेशन को निष्पादित करने का प्रयास करते हैंdoubleOfNewWay
, तो परिणाम थाNaN
, क्योंकि हम कई वादे नहीं कर सकते (जाहिर है!)- गुणा करना
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]