Async: ๋ฌธ์„œ์—๋Š” ๋” ๋‚˜์€ ์˜ˆ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2019๋…„ 01์›” 14์ผ  ยท  21์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: caolan/async

์ง€๋„์— ๋Œ€ํ•ด ์ด ์˜ˆ๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

async.map(['file1','file2','file3'], fs.stat, function(err, results) {
    // results is now an array of stats for each file
});

์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ตฌ๋ฌธ ์™ธ์—๋Š” ์•„๋ฌด ๊ฒƒ๋„ ์•Œ๋ ค์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์‚ฌ๋žŒ๋“ค์€ fs.stat ๋ฅผ ํ†ต๊ณผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ์—๋Š” ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์˜ต์…˜์˜ ์‚ฌ์šฉ์ด ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ธฐ๋Šฅ ๋ฐ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋ชจ๋“  ์˜ˆ์ œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋„ˆ๋ฌด ๋‹จ์ˆœํ•˜๋‹ค

docs help wanted

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํ›จ์”ฌ ๋” ๋‚˜์€ ๋ฌธ์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ async/await๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŽ์€ ์˜ˆ์ œ๋ฅผ ๋ณ€๊ฒฝ(๋˜๋Š” mroe ์˜ˆ์ œ ์ถ”๊ฐ€)ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ํ˜„์žฌ ๋‚˜์—๊ฒŒ ์—†๋Š” ์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  21 ๋Œ“๊ธ€

๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํ›จ์”ฌ ๋” ๋‚˜์€ ๋ฌธ์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ async/await๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŽ์€ ์˜ˆ์ œ๋ฅผ ๋ณ€๊ฒฝ(๋˜๋Š” mroe ์˜ˆ์ œ ์ถ”๊ฐ€)ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ํ˜„์žฌ ๋‚˜์—๊ฒŒ ์—†๋Š” ์‹œ๊ฐ„์ด ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋„์šธ ์ˆ˜ ์žˆ์„์ง€๋„ ๋ชฐ๋ผ.

์˜ˆ์‹œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋„์™€๋“œ๋ฆด๊นŒ์š”?

  • async / await ๋” ๋งŽ๊ณ  ์ฝœ๋ฐฑ์ด ์ ์€ ์˜ˆ
  • ์‹ค์ œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ ์˜ˆ, ์ ์€ foo / bar
  • Async์˜ "์Šค์œ„ํŠธ ์ŠคํŒŸ"์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ๋“ค -- ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด๋Š” ํ•˜๊ธฐ ํž˜๋“  ๊ฒƒ๋“ค
  • ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํ๋ฆ„์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ๋Š” Node/JS๋ฅผ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐœ๋ณ„ ๋ฐฉ๋ฒ•์˜ ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ณด๋‹ค ํฌ๊ด„์ ์ธ ์˜ˆ

๋Œ€๋ถ€๋ถ„์˜ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ 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()])
  )
);
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰