आपको अपने पुनरावर्ती फ़ंक्शन कॉल को एक में लपेटना चाहिए
setTimeout
,
setImmediate
या
process.nextTick
नोड को देने के लिए फ़ंक्शन। स्टैक को खाली करने का मौका देता है। यदि आप ऐसा नहीं करते हैं और बिना किसी वास्तविक async फ़ंक्शन कॉल के कई लूप हैं या यदि आप कॉलबैक की प्रतीक्षा नहीं करते हैं, तो आपका अपरिहार्यRangeError: Maximum call stack size exceeded
होगा ।
"संभावित Async लूप" के विषय में कई लेख हैं। यहाँ एक है ।
अब कुछ और उदाहरण कोड:
var condition = false,
max = 1000000;
function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
potAsyncLoop( i+1, resume );
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
...
});
यह सही है:
var condition = false,
max = 1000000;
function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
setTimeout( function() {
potAsyncLoop( i+1, resume );
}, 0 );
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
...
});
अब आपका लूप बहुत धीमा हो सकता है, क्योंकि हम प्रति चक्कर थोड़ा समय (एक ब्राउज़र राउंडट्रिप) ढीला कर देते हैं। लेकिन आपको setTimeout
हर दौर में फोन करने की जरूरत नहीं है । आम तौर पर यह हर 1000 वें समय में करना ठीक है। लेकिन यह आपके स्टैक आकार के आधार पर भिन्न हो सकता है:
var condition = false,
max = 1000000;
function potAsyncLoop( i, resume ) {
if( i < max ) {
if( condition ) {
someAsyncFunc( function( err, result ) {
potAsyncLoop( i+1, callback );
});
} else {
if( i % 1000 === 0 ) {
setTimeout( function() {
potAsyncLoop( i+1, resume );
}, 0 );
} else {
potAsyncLoop( i+1, resume );
}
}
} else {
resume();
}
}
potAsyncLoop( 0, function() {
...
});