์ง๋์ ๋ํด ์ด ์๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
async.map(['file1','file2','file3'], fs.stat, function(err, results) {
// results is now an array of stats for each file
});
์ด๊ฒ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ๋ฌธ ์ธ์๋ ์๋ฌด ๊ฒ๋ ์๋ ค์ฃผ์ง ์์ต๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ฌ๋๋ค์ fs.stat
๋ฅผ ํต๊ณผํ์ง ์์ต๋๋ค. ์์ ์๋ ๊ฐ๋ฅํ ๋ชจ๋ ์ต์
์ ์ฌ์ฉ์ด ํฌํจ๋์ด์ผ ํฉ๋๋ค. ๋ชจ๋ ๊ธฐ๋ฅ ๋ฐ ๋ฉ์๋์ ๋ํ ๋ชจ๋ ์์ ๋ฅผ ์
๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ๊ทธ๋ค์ ๋๋ฌด ๋จ์ํ๋ค
๋์ํฉ๋๋ค. ํจ์ฌ ๋ ๋์ ๋ฌธ์๊ฐ ํ์ํฉ๋๋ค. ๋ํ async/await๋ฅผ ์ฌ์ฉํ๋๋ก ๋ง์ ์์ ๋ฅผ ๋ณ๊ฒฝ(๋๋ mroe ์์ ์ถ๊ฐ)ํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ํ์ฌ ๋์๊ฒ ์๋ ์๊ฐ์ด ํ์ํ ๊ฒ์ ๋๋ค.
๋ด๊ฐ ๋์ธ ์ ์์์ง๋ ๋ชฐ๋ผ.
์์๋ฅผ ์ด๋ป๊ฒ ๋์๋๋ฆด๊น์?
async
/ await
๋ ๋ง๊ณ ์ฝ๋ฐฑ์ด ์ ์ ์foo
/ bar
๋๋ถ๋ถ์ ๋ฉ์๋์ ๋ํ JSDoc ์ฃผ์์๋ @example
๋ธ๋ก์ด ์์ต๋๋ค. ๋ฏธ์ณค์ด!
๊ทธ ํน์ ์์ ๋ํด ๋ฉ๋ชจํ์ญ์์ค.
await async.map(['file1','file2','file3'], fs.promises.stat);
// or without async lib
await Promise.all(['file1','file2','file3'].map(name => fs.promises.stat(name))
๋๋ ๊ฒฐ๊ณผ๋ก ๊ฐ์ฒด๋ฅผ ์ํ๋ ๊ฒฝ์ฐ
await async.auto({
file1: async()=>fs.promises.stat('file1'),
file2: async()=>fs.promises.stat('file2')
file3: async()=>fs.promises.stat('file3')
})
// or without async lib
Object.fromEntries(
await Promise.all(['file1','file2','file3'].map(async name => [name, await fs.promises.stat(name)]))
)
ํนํ async/await ์์ด๋ async.mapLimit์ (๋จ์ํ) Promise ๊ธฐ๋ฐ ์์ ๋ฅผ ์ฐพ๊ณ ์์ต๋๋ค. ์ง๊ธ๊น์ง ์ฝ๋ฐฑ์ด ์๋ ์์ ๋ฅผ ์ ํ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
@flatcoding https://github.com/caub/misc/blob/master/utils/promise-concurrent.js , await
์ํ์ง ์์ผ๋ฉด ์ฌ๊ท ํจ์๋ก ๋์ฒดํ ์ ์์ต๋๋ค.
์๋
ํ์ธ์ ์๋ฆด @caub ,
๋ต์ฅ์ ๋ณด๋ด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ์ ๋ ํนํ 'await'์ ๋ฐ๋ํ๋ ๊ฒ์ด ์๋๋ผ 'async' ๋ชจ๋์ ๋ํ '์ข์ ์'๋ฅผ ์ํด ์์ํ๊ณ .then .catch๋ฅผ ํฌํจํ ๊ธฐ๋ณธ Promise ์ฒ๋ฆฌ๊ฐ ํฌํจ๋ ๊ตฌํ์ ๋ณด๊ณ ์ถ์ต๋๋ค.
๋๋ ์์งํ ์ผ๋ฐ์ ์ผ๋ก Promises์ ํจ๊ป async๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช๊ณ ์์ผ๋ฏ๋ก async/await๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ 1) ๋จ๊ณ๋ถํฐ ์์ํ๊ณ ์ถ์ต๋๋ค.
Btw., ๊ทํ์ ์์ ๋ฅผ ๊ณต์ ํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋น๋๊ธฐ ๋ชจ๋๊ณผ ์ด๋ป๊ฒ ๊ด๋ จ๋์ด ์๋์ง๋ ํ์คํ์ง ์์ต๋๋ค.
"๊ฐ๋จํ ์ฝ์ ๊ธฐ๋ฐ ์์ "๋ผ๊ณ ์๊ฐํ๋๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ ์์ ๋ฅผ ์๋ฏธํ์ต๋๋ค.
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์์ ๋ฅผ ์ํ์ ๋ค๋ฉด
๋ง์ต๋๋ค. ๊ทธ๋์ ์ ๋ ์ผ๋ฐ์ ์ผ๋ก Promises๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ผ๋ฉฐ ์ฝ๋ฐฑ ์คํ์ผ์์ 'async' ๋ชจ๋์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๊ณ ์์ต๋๋ค. ๋ฌธ์์ ๋ช
์๋ ๋๋ก ์ฝ๋ฐฑ์ด ์ ๊ณต๋์ง ์์ผ๋ฉด ์ฝ์์ด ๋ฐํ๋ฉ๋๋ค. ์ง๊ธ๊น์ง๋ ์ ์ด๋ async.map(Limit)์ด ์๋ ์ข์ ์๋ฅผ ๋ณผ ์ ์์์ต๋๋ค. ์ด ์ค๋ ๋๋ ๋ฌธ์์ '๋ ๋์ ์'์ ๊ดํ ๊ฒ์ด๋ฏ๋ก ์ฌ๊ธฐ์์ ์ด์ ๋ํด ์ธ๊ธํ์ต๋๋ค...
๊ทธ๋ฆฌ๊ณ ๋งํ๋ฏ์ด ๋๋ Promise๋ฅผ ์คํ์ ์ฎ๊ธธ ์ ์์๊ณ ์ฌ์ง์ด ๊ทธ๊ฒ์ ๋ํด ๋ฌธ์ ๋ฅผ ์ ๊ธฐํ์ต๋๋ค.
์๋ ํ์ธ์ @caub๋ , ์ฝ๋ฐฑ, ์ฝ์ ๋ฐ async/await์ ๋ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ถ๊ฐํ๊ณ ์ปฌ๋ ์ ๋ฉ์๋์ ๋ํ ๋ฌธ์๋ฅผ ๊ฐ์ ํ๋ ๋ฐ
@romanbalayan ๊ตฟ
์ฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ async.parallel
์ async.auto
. ์ด ๋ฐฉ๋ฒ๋ ๋ค๋ฃฐ ๊ณํ์ธ๊ฐ์?
์ฐธ๊ณ : async/await ์์ ์์ async IIFE (async ()=>{
๋ฅผ ํผํ์ฌ ๋ ๊ฐ๋ณ๊ฒ ๋ง๋ค ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
@caub , IIFE๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด pull ์์ฒญ์ ์ ๋ฐ์ดํธํ์ต๋๋ค. (์ํ์ด ์ค์ ๋ก ์๋ํ๋์ง ๋ก์ปฌ์์ ํ ์คํธํ๋ ๋ฐ ์ฌ์ฉํ์ต๋๋ค)
์, ํ๋ฆ ์ ์ด๋ ๊ณง ๋ค๋ฃจ๊ณ ์ถ์ต๋๋ค. ๋๋ ์ปฌ๋ ์ ์์ ์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ด ์ฌ๊ธฐ์์ ๊ธฐ๋ํ ๊ฒ๊ณผ ์ผ์นํ๋์ง ์ค์ ๋ก ํผ๋๋ฐฑ์ ๊ธฐ๋ค๋ฆฌ๊ณ ์์์ต๋๋ค.
@romanbalayan ๋น์ ์ด ํ ์ ์๋ ์ผ์ ํด๋น PR ๋ถ๊ธฐ๋ฅผ github ํ์ด์ง๋ก ์ค์ ํ๋ ๊ฒ์ ๋๋ค(๋น๋๊ธฐ ํฌํฌ๋ก ์ด๋, ์ค์ > Github ํ์ด์ง > ์์ค: (PR ๋ถ๊ธฐ ์ ํ)). ๊ทธ๋ฌ๋ฉด http://romanbalayan.github ์์ ๋ฏธ๋ฆฌ ๋ณผ ์ ์์ต๋๋ค
@caub , ์ข์ ์๊ฐ์ ๋๋ค. ๊ทธ๋ ๊ฒ ํ์ผ๋ฉฐ ์ง๊ธ https://romanbalayan.github.io/async/v3/์์ ์ฌ์ฉํ ์ ์์ด์ผ ํฉ๋๋ค.
์๋ ํ์ธ์ @caub ๋
ํ๋ฆ ์ ์ด ๋ฉ์๋์ ๋ํ Promise ๋ฐ async/await ์ํ ์ถ๊ฐ - async.parallel
, async.series
๋ฐ async.auto
@romanbalayan ์ข์์ ! https://romanbalayan.github.io/async/v3/docs.html#auto
์ฝ๋ฐฑ๊ณผ ์ฝ์์ ์๋ ํญ์ ๋งค์ฐ ์ ์ฌํ๋ฉฐ ์๋ง๋ ๊ทธ ์ค ํ๋๋ง ๊ฐ์ง ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด์จ๋ ์ฝ์์ ์ฌ์ฉํ ๋ ์ฐ๋ฆฌ๋ ๋น๋๊ธฐ/๋๊ธฐ๋ฅผ ์ ํํ๊ณ ๋ด์ฉ์ ๊ฐ๋ณ๊ฒ ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ค๋ฅธ ์ข์ ๊ฒ๋ค!
@์บ
Collections ๋ฉ์๋์์๋ Promise ์ฌ์ฉ ์์ ๋ฅผ ์ ๊ฑฐํด์ผ ํฉ๋๊น?
๋ค ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค
๋ํ ํ๋ฆ ์ ์ด ๋ฐฉ๋ฒ์ ๊ฒฝ์ฐ ๋น๋๊ธฐ ๋ด๋ถ ํจ์๊ฐ ์๋ ์์ ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์:
const delay = (t, v) => new Promise(r => setTimeout(r, t, v));
try {
console.time('parallel')
const results = await async.parallel({
one: async () => delay(200, 1),
two: async () => delay(100, 2),
});
console.timeLog('parallel', results);
// parallel: 200ms { one: 1, two: 2 }
}
catch (err) {
console.log(err);
}
@romanbalayan ํ๋ฅญํ ์ํ์
๋๋ค. ๋ฉฐ์น ์ ์ ๋ฌธ์ ๋ฒ์ ์ ์ฐพ์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค! ๊ฒฐ๊ตญ ์ํ ์ฐฉ์ค๋ฅผ ํตํด ์ผ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์์ ๋์ง๋ง ์๋ก์ด ์์ ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๊ณ ํต ์ค๋ฌ์ธ ๊ฒ์
๋๋ค :-)
async/await ๋ฐ Promise.all๊ณผ Promise.allSettled๊ฐ ์์ผ๋ฏ๋ก ์ผ๋ถ ๋น๋๊ธฐ ๋ฉ์๋์ ์ ์ฉ์ฑ์ ๋ํด 100% ํ์ ํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ด ์์ ์์ ๋ชจ๋ ๋ฉ์๋์ ๋์ผํ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ด ์๋์ง ๊ถ๊ธํฉ๋๋ค. . (?)
const results = await async.parallel({
one: async () => delay(200, 1),
two: async () => delay(100, 2),
});
๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ์์ฑ๋ฉ๋๋ค.
const results = Object.fromEntries(
await Promise.all(
Object.entries({
one: async () => delay(200, 1),
two: async () => delay(100, 2),
})
.map(async ([k, v]) => [k, await v()])
)
);
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋์ํฉ๋๋ค. ํจ์ฌ ๋ ๋์ ๋ฌธ์๊ฐ ํ์ํฉ๋๋ค. ๋ํ async/await๋ฅผ ์ฌ์ฉํ๋๋ก ๋ง์ ์์ ๋ฅผ ๋ณ๊ฒฝ(๋๋ mroe ์์ ์ถ๊ฐ)ํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ํ์ฌ ๋์๊ฒ ์๋ ์๊ฐ์ด ํ์ํ ๊ฒ์ ๋๋ค.