for
पाश तुरंत पूरा होने के लिए चलाता है जबकि आपके सभी एसिंक्रोनस ऑपरेशन शुरू हो जाते हैं। जब वे भविष्य में कुछ समय पूरा करते हैं और कॉलबैक कहते हैं, तो आपके लूप इंडेक्स वैरिएबल i
का मूल्य सभी कॉलबैक के लिए अंतिम मूल्य होगा।
ऐसा इसलिए है क्योंकि for
लूप लूप के अगले पुनरावृत्ति पर जारी रखने से पहले एक एसिंक्रोनस ऑपरेशन को पूरा करने की प्रतीक्षा नहीं करता है और क्योंकि एसिंक कॉलबैक को भविष्य में कुछ समय कहा जाता है। इस प्रकार, लूप इसके पुनरावृत्तियों को पूरा करता है और फिर उन एसिंक ऑपरेशन समाप्त होने पर कॉलबैक को कॉल किया जाता है। इस प्रकार, लूप इंडेक्स "किया गया" है और सभी कॉलबैक के लिए इसके अंतिम मूल्य पर बैठा है।
इसके आसपास काम करने के लिए, आपको प्रत्येक कॉलबैक के लिए अलग-अलग लूप इंडेक्स को अलग से सहेजना होगा। जावास्क्रिप्ट में, ऐसा करने का तरीका इसे फ़ंक्शन क्लोजर में कैप्चर करना है। यह या तो किया जा सकता है विशेष रूप से इस उद्देश्य के लिए एक इनलाइन फ़ंक्शन क्लोजर बनाना (नीचे दिखाया गया पहला उदाहरण) या आप एक बाहरी फ़ंक्शन बना सकते हैं जिसे आप इंडेक्स पास करते हैं और इसे आपके लिए विशिष्ट रूप से इंडेक्स को बनाए रखने दें (नीचे दिखाया गया दूसरा उदाहरण)।
2016 के रूप में, यदि आप जावास्क्रिप्ट की एक पूरी तरह से अप-टू-कल्पना ES6 कार्यान्वयन है, तो आप भी let
उपयोग कर सकते हैं for
पाश चर को परिभाषित करने के लिए और इसे विशिष्ट (for
पाश से प्रत्येक यात्रा तीसरे कार्यान्वयन के लिए परिभाषित किया जाएगा नीचे)। लेकिन, ध्यान दें कि यह ES6 कार्यान्वयन में देर से कार्यान्वयन सुविधा है, इसलिए आपको यह सुनिश्चित करना होगा कि आपका निष्पादन वातावरण उस विकल्प का समर्थन करता है।
उपयोग करें।foreach() पुनरावृति है, क्योंकि यह बनाता है अपनी ही समारोह बंद
someArray.forEach(function(item, i) {
asynchronousProcess(function(item) {
console.log(i);
});
});
अपनी खुद समारोह बंद बनाएँ Iife का उपयोग
var j = 10;
for (var i = 0; i < j; i++) {
(function(cntr) {
// here the value of i was passed into as the argument cntr
// and will be captured in this function closure so each
// iteration of the loop can have it's own value
asynchronousProcess(function() {
console.log(cntr);
});
})(i);
}
या बाहरी समारोह संशोधित करें और यह चर
दर्रा
यदि आप asynchronousProcess()
फ़ंक्शन को संशोधित कर सकते हैं, तो आप वहां केवल मान पास कर सकते हैं और asynchronousProcess()
इस तरह कॉलबैक करने के लिए वापस CNTR काम करते हैं:
var j = 10;
for (var i = 0; i < j; i++) {
asynchronousProcess(i, function(cntr) {
console.log(cntr);
});
}
उपयोग ES6 let
आप Javascript निष्पादन वातावरण है कि पूरी तरह से समर्थन करता है ES6 है, तो आप let
अपने for
पाश इस तरह में उपयोग कर सकते हैं:
const j = 10;
for (let i = 0; i < j; i++) {
asynchronousProcess(function() {
console.log(i);
});
}
let
एक for
पाश घोषणा में घोषित की तरह इस एक uni पैदा करेगा लूप के प्रत्येक आमंत्रण के लिए i
का que मान (जो आप चाहते हैं)। अपने async समारोह एक वादा देता है, तो
वादों और async साथ Serializing/इंतजार
, और आप के बजाय समानांतर में की एक के बाद एक को चलाने के लिए अपने async संचालन क्रमानुसार करने चाहते हैं और आप एक आधुनिक में चला रहे हैं पर्यावरण जो async
और await
का समर्थन करता है, तो आपके पास और विकल्प हैं।
async function someFunction() {
const j = 10;
for (let i = 0; i < j; i++) {
// wait for the promise to resolve before advancing the for loop
await asynchronousProcess();
console.log(i);
}
}
यह सुनिश्चित करें कि asynchronousProcess()
को केवल एक कॉल एक समय में उड़ान में है और for
पाश भी जब तक हर एक से किया जाता है अग्रिम नहीं होगा कर देगा। यह पिछली योजनाओं से अलग है जो सभी ने आपके असीमित परिचालन को समानांतर में चलाया है, इसलिए यह पूरी तरह से निर्भर करता है कि आप किस डिज़ाइन को चाहते हैं। नोट: await
एक वादे के साथ काम करता है ताकि आपके फ़ंक्शन को एक ऐसा वादा वापस कर दिया जाए जिसे एसिंक्रोनस ऑपरेशन पूरा होने पर हल/अस्वीकार कर दिया गया हो। साथ ही, ध्यान दें कि await
का उपयोग करने के लिए, युक्त फ़ंक्शन को async
घोषित किया जाना चाहिए।
'पैरामीटर को' asynchronousProcess' फ़ंक्शन में जोड़ने के बारे में कैसे? जो इसे कॉलबैक पर पास कर सकता है फंक्शन –
संभावित डुप्लिकेट [जावास्क्रिप्ट बंद लूप के अंदर बंद करना - सरल व्यावहारिक उदाहरण] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –