async = require('async');
var documents = ['a', 'b', 'c', 'd', 'e', 'f'];
async.forEachLimit(documents, 2, function(item, callback) {
console.log(".", item);
callback(null);
}, function(err){
console.log("end", err);
});
ํต๋๋ฌด
$ node test.js
. a
. a
. a
. a
. a
. a
end undefined
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
. b
[...]
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
RangeError: Maximum call stack size exceeded
forEachLimit
์ด ์๋ชป๋ ๊ฒ ๊ฐ์ต๋๋ค.
started += 1
running += 1
iterator ํธ์ถ ์์ผ๋ก ์ด๋ํด์ผ ํฉ๋๋ค. arr[started]
๋ arr[started - 1]
๋ก ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค.
์ฐธ๊ณ : iterator iterator ๋ด๋ถ์ ์ฝ๋๊ฐ ๋์ผํ ํฑ์์ ์ฝ๋ฐฑ์ ํธ์ถํ๋ ๊ฒฝ์ฐ์๋ง ์ด ๋ฒ๊ทธ๊ฐ ๋ฐ์ํฉ๋๋ค.
async.js์์ SYNC ํจ์ ํธ์ถ ์ค์ง
๋ด ๋ฐ๋ณต๊ธฐ์ ์กฐ๊ฑด๋ถ return callback(null);
๊ฐ ์์ ๋ ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. async.forEach
#$ ๋ฅผ ์ ์ฉํ๊ธฐ ์ ์ Array.filter
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด์ ํํฐ๋งํ๋ ๋ ๋๋ํ ์ผ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ค์ ๋ก ๋์์ด ๋์์ต๋๋ค...
ํด์ผ ํ๋ค๊ณ ์๊ฐํ๋ค๋ฉด process.nextTick(function() { callback(); })
๋ฅผ ์ฌ์ฉํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
@jacobrask ์ ์๋ํ์ต๋๋ค. ๊ฐ์ฌ ํด์
callback(null);
๋ฅผ ์ํํ๋ ๊ฒ์ ๋๊ธฐ์์
๋๋ค. process.nextTick(callback)
๋๋ process.nextTick(function() { callback(null); });
์ ๊ฐ์ด ๋น๋๊ธฐ์์ผ๋ก ํธ์ถํด์ผ ํฉ๋๋ค. @bobrik์ด ๋งํ๋ฏ์ด ๋น๋๊ธฐ์์ ๋๊ธฐํ ํจ์ ํธ์ถ์ ์ค์งํ์ญ์์ค. :)
"๋น๋๊ธฐ์์ ๋๊ธฐํ ํจ์ ํธ์ถ ์ค์ง"๋ ์์ ์ ๋์น๊ณ ์์ต๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ณ forEachLimit์์๋ง ๋ฌธ์ ๊ฐ ๋๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
async.forEachLimit(['a','b'], 1, function(item, callback){
if(something) {
doStuff(function(){ callback(); });
} else {
callback();
}
});
@jacobrask ๊ฐ ํํฐ๋ง์ผ๋ก ์ธ๊ธํ ๊ฒ์ฒ๋ผ ๋งค์ฐ ๊ตฌ์ฒด์ ์ธ ์์ ์ ๋ํด ์๋นํ ์ฝ๊ฒ ๋ณดํธํ ์ ์์ง๋ง doStuff()(๋ด ์ ์ด ์ธ๋ถ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ ์ ์์)๊ฐ process.nextTick() ์์ด ๋ด ์ฝ๋ฐฑ์ ํธ์ถํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
์ด๋ฌํ ๊ฒฝ์ฐ ์คํ ์ค๋ฒํ๋ก๋ฅผ ๋ฐฉ์งํด์ผ ํ๋ ๋๊ธฐ ๋ฐ๋ณต์๋ฅผ ๊ฐ์งํ๋ ๊ฒฝ์ฐ async.nextTick์ ํธ์ถํ๋ ๋ช ๊ฐ์ง ์ฝ๋๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ง์งํ๊ฒ, ASYNC์์ SYNC ํจ์ ํธ์ถ์ ์ค์งํ์ญ์์ค! ... ๋์ ์ผ๊ด๋๊ฒ ๋๊ธฐ์ ๋๋ ์ผ๊ด๋๊ฒ ๋น๋๊ธฐ์์ผ๋ก ๊ธฐ๋ฅ์ ๋ง๋์ญ์์ค. ;)
์ด๊ฒ์ async.eachSeries
์์๋ ๋ฐ์ํ์ต๋๋ค.
๋ํ mapLimit
์์ ๋ฐ์ํฉ๋๋ค. ์, ๋ด ํจ์๋ ๋ชจ์ ํจ์์ด๊ธฐ ๋๋ฌธ์ ๋๊ธฐํ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ setImmediate
๋ก ๊ฐ์ธ์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
async.forEachOfLimit
์์ ๋ง๋๋ณด์ธ์
async.waterfall
์ ๋์ผํ ๋ฌธ์ ์ ์ง๋ฉดํ์ต๋๋ค.
๋ฌผ๋ก async.queue๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
๋๊ธฐํ ์์ ์ ํ๊ณ ์์์ต๋๋ค. ๋ค์์์ ๋ณ๊ฒฝํ์ฌ ์์ ํ์ต๋๋ค.
callback();
์๊ฒ
setTimeout(callback, 0);
์ด๊ฒ์ ์ฝ์์ ์บ์น๊ฐ ๋ถ์์ ๋ ๋์๊ฒ ์ผ์ด๋ฌ์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๊ฒ:
async.forEach(items, (item:any, callback:Function) => {
someAsyncPromise(item).then(() => {
callback();
}).catch((err) => {
//console error or something here
callback();
})
});
์ด ์ค๋ฅ๋ promise์์ ์์ธ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ์๋ง ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ catch๋ promise์ ๋น๋๊ธฐ ๋นํธ ์ ์ throw๋์ด์ผ ํฉ๋๋ค.
`
๋๋ ์ฐ๋ฆฌ๊ฐ ๋น๋๊ธฐ์์ผ๋ก ๋๊ธฐํ ํจ์ ํธ์ถ์ ์ค๋จํด์ผ ํ๋ค๋ ๊ฒ์ ์ดํดํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋น๋๊ธฐ ๋ณธ๋ฌธ ๋ด์์ ๋๊ธฐํ ํจ์ callback()์ ํธ์ถํ๋ ๊ฒ์ด ์๋ชป๋ ๊ฒฝ์ฐ ๋น๋๊ธฐ ๋ฌธ์์ ์์ ์์ ํ์๋๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
๋๊ตฐ๊ฐ ๋์ ๋น๋๊ธฐ ๋ชจ๋๋ก ์์ ํ๋ '์ ์ ํ' ๋ฐฉ๋ฒ์ด ๋ฌด์์ธ์ง ์ดํดํ๋๋ก ๋์์ค ์ ์์ต๋๊น?
๋ค์์ ๋น๋๊ธฐ ์ค๋ช ์์์ ์ง์ ๊ฐ์ ธ์จ ์์ ๋๋ค.
// assuming openFiles is an array of file names
async.each(openFiles, function(file, callback) {
// Perform operation on file here.
console.log('Processing file ' + file);
if( file.length > 32 ) {
console.log('This file name is too long');
callback('File name too long');
} else {
// Do work to process file here
console.log('File processed');
callback();
}
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
https://caolan.github.io/async/docs.html#each
๊ฐ์ฌ ํด์!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๊ธฐํ ์์ ์ ํ๊ณ ์์์ต๋๋ค. ๋ค์์์ ๋ณ๊ฒฝํ์ฌ ์์ ํ์ต๋๋ค.
์๊ฒ