JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„. Sergey Omelnitsky๋‹˜์ด ์—ฐ๋ฝํ•˜์…จ์Šต๋‹ˆ๋‹ค. ์–ผ๋งˆ ์ „ ์ €๋Š” ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๊ด€ํ•œ ์ŠคํŠธ๋ฆผ์„ ์ฃผ์ตœํ•˜์—ฌ JavaScript์˜ ๋น„๋™๊ธฐ์„ฑ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜ ์ €๋Š” ์ด ์ž๋ฃŒ์— ๋Œ€ํ•ด ๋ฉ”๋ชจ๋ฅผ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

ํ•˜์ง€๋งŒ ์ฃผ์š” ๋‚ด์šฉ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์†Œ๊ฐœ ๊ธ€์„ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ •์˜๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์Šคํƒ๊ณผ ํ๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€์š”?

์Šคํƒ ํ›„์ž…์„ ์ถœ LIFO ๋ฐฉ์‹์œผ๋กœ ์š”์†Œ๋ฅผ ์–ป๋Š” ์ปฌ๋ ‰์…˜์ž…๋‹ˆ๋‹ค.

์—ด ์„ ์ž… ์„ ์ถœ FIFO ๋ฐฉ์‹์œผ๋กœ ์š”์†Œ๋ฅผ ์–ป๋Š” ์ปฌ๋ ‰์…˜์ž…๋‹ˆ๋‹ค.

์ข‹์•„, ๊ณ„์†ํ•˜์ž.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

JavaScript๋Š” ๋‹จ์ผ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‹คํ–‰ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ๊ณ  ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์„ ์œ„ํ•ด ๋Œ€๊ธฐํ•˜๋Š” ์Šคํƒ์ด ํ•˜๋‚˜๋ฟ์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ JavaScript๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด ๋‹ค๋ฅธ ์ž‘์—…์€ ํ˜ธ์ถœ๋  ๋•Œ๊นŒ์ง€ ์Šคํƒ์—์„œ ์ฐจ๋ก€๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

ํ˜ธ์ถœ ์Šคํƒ ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์žˆ๋Š” ์œ„์น˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ํ•ญ๋ชฉ์„ ์Šคํƒ ๋งจ ์œ„๋กœ ํ‘ธ์‹œํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์—์„œ ๋Œ์•„์˜ฌ ๋•Œ ์Šคํƒ์˜ ์ตœ์ƒ์œ„ ์š”์†Œ๋ฅผ ํŒํ•˜๊ณ  ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ์œ„์น˜๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์Šคํƒ์ด ํ•  ์ˆ˜ ์žˆ๋Š” ์ „๋ถ€์ž…๋‹ˆ๋‹ค. ์ด์ œ ๋งค์šฐ ํฅ๋ฏธ๋กœ์šด ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด JavaScript์—์„œ ๋น„๋™๊ธฐ์„ฑ์€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

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

๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ๋‹จ๊ณ„๋ณ„ ๊ตฌํ˜„์„ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‹œ์Šคํ…œ์—์„œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

console.log('Hi');
setTimeout(function cb1() {
    console.log('cb1');
}, 5000);
console.log('Bye');

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

1) ์•„์ง ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์€ ๊นจ๋—ํ•˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์€ ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

2) ๊ทธ๋Ÿฐ ๋‹ค์Œ console.log('Hi') ๋ช…๋ น์ด ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

3) ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ์„ฑ์ทจ๋˜์—ˆ์Šต๋‹ˆ๋‹ค

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

4) ๊ทธ๋Ÿฐ ๋‹ค์Œ console.log('Hi')๊ฐ€ ํ˜ธ์ถœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

5) ์ด์ œ setTimeout(function cb1() {โ€ฆ }) ๋ช…๋ น์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

6) setTimeout(function cb1() {โ€ฆ }) ๋ช…๋ น์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๋Š” Web API์˜ ์ผ๋ถ€์ธ ํƒ€์ด๋จธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์นด์šดํŠธ๋‹ค์šด์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

7) setTimeout(function cb1() {... }) ๋ช…๋ น์ด ์ž‘์—…์„ ์™„๋ฃŒํ•˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

8) console.log('Bye') ๋ช…๋ น์ด ํ˜ธ์ถœ ์Šคํƒ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

9) console.log('Bye') ๋ช…๋ น์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

10) console.log('Bye') ๋ช…๋ น์ด ํ˜ธ์ถœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

11) ์ตœ์†Œ 5000ms๊ฐ€ ์ง€๋‚˜๋ฉด ํƒ€์ด๋จธ๊ฐ€ ์ข…๋ฃŒ๋˜๊ณ  ์ฝœ๋ฐฑ cb1์ด ์ฝœ๋ฐฑ ๋Œ€๊ธฐ์—ด์— ๋ฐฐ์น˜๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

12) ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ์ฝœ๋ฐฑ ํ์—์„œ ํ•จ์ˆ˜ cb1์„ ๊ฐ€์ ธ์™€ ํ˜ธ์ถœ ์Šคํƒ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

13) cb1 ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ  ํ˜ธ์ถœ ์Šคํƒ์— console.log('cb1')๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

14) console.log('cb1') ๋ช…๋ น์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

15) console.log('cb1') ๋ช…๋ น์ด ํ˜ธ์ถœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

16) ํ•จ์ˆ˜ cb1์ด ํ˜ธ์ถœ ์Šคํƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

์—ญํ•™์˜ ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์ž, ์šฐ๋ฆฌ๋Š” JavaScript์—์„œ ๋น„๋™๊ธฐ์„ฑ์ด ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋˜๋Š”์ง€ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ๋ฐœ์ „์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ์ด์•ผ๊ธฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ์ง„ํ™”.

a(function (resultsFromA) {
    b(resultsFromA, function (resultsFromB) {
        c(resultsFromB, function (resultsFromC) {
            d(resultsFromC, function (resultsFromD) {
                e(resultsFromD, function (resultsFromE) {
                    f(resultsFromE, function (resultsFromF) {
                        console.log(resultsFromF);
                    })
                })
            })
        })
    })
});

์šฐ๋ฆฌ๊ฐ€ JavaScript๋กœ ์•Œ๊ณ  ์žˆ๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ํ•จ์ˆ˜์— ์˜ํ•ด์„œ๋งŒ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ์€ ์ด๋ ‡๊ฒŒ ํƒ„์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ์Šฌํ””, ์šฐ์šธ, ์Šฌํ””์œผ๋กœ ๋ณ€ํ•  ๋•Œ๊นŒ์ง€ ๋ฉ‹์ง€๊ณ , ์žฌ๋ฏธ์žˆ๊ณ , ์œ ์พŒํ•ฉ๋‹ˆ๋‹ค. ์™œ? ๊ฐ„๋‹จ ํ•ด:

  • ์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ํ”„๋กœ์ ํŠธ๋Š” ๋น ๋ฅด๊ฒŒ ๋ชจํ˜ธํ•˜๊ณ  ๋ฐ˜๋ณต์ ์œผ๋กœ ์ค‘์ฒฉ๋œ ๋ธ”๋ก, ์ฆ‰ "์ฝœ๋ฐฑ ์ง€์˜ฅ"์œผ๋กœ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋Š” ๋†“์น˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.
  • return์„ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„์‹์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Promise์˜ ์ถœํ˜„์œผ๋กœ ์ƒํ™ฉ์€ ์กฐ๊ธˆ ๋‚˜์•„์กŒ์Šต๋‹ˆ๋‹ค.

new Promise(function(resolve, reject) {
    setTimeout(() => resolve(1), 2000);

}).then((result) => {
    alert(result);
    return result + 2;

}).then((result) => {
    throw new Error('FAILED HERE');
    alert(result);
    return result + 2;

}).then((result) => {
    alert(result);
    return result + 2;

}).catch((e) => {
    console.log('error: ', e);
});

  • ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” Promise ์ฒด์ธ์ด ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.
  • ์˜ค๋ฅ˜๋ฅผ ์žก๋Š” ๋ณ„๋„์˜ ๋ฐฉ๋ฒ•์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.
  • Promise.all์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ ์‹คํ–‰ ๊ฐ€๋Šฅ์„ฑ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • async/await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘์ฒฉ๋œ ๋น„๋™๊ธฐ์„ฑ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๊ธ€์Ž„์š”, ์šฐ๋ฆฌ๋Š” ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ˆœ์กฐ๋กญ๊ฒŒ ์ ‘๊ทผํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”ผ๊ณคํ•œ? ๋‹คํ–‰ํžˆ๋„ ์ฐจ๋ฅผ ๋“์—ฌ์„œ ์ƒ๊ฐํ•ด๋ณด๊ณ  ๋‹ค์‹œ ์™€์„œ ๋” ๋งŽ์€ ๋‚ด์šฉ์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ณ„์†ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐโ€Š๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ ๋ณ€๊ฒฝ ์ „ํŒŒ์— ์ดˆ์ ์„ ๋งž์ถ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์ด ๋ฌด์—‡์ธ์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

// ะŸะพะปัƒั‡ะฐะตะผ ััั‹ะปะบัƒ ะฝะฐ ัะปะตะผะตะฝั‚
const input = ducument.querySelector('input');

const eventsArray = [];

// ะŸัƒัˆะธะผ ะบะฐะถะดะพะต ัะพะฑั‹ั‚ะธะต ะฒ ะผะฐััะธะฒ eventsArray
input.addEventListener('keyup',
    event => eventsArray.push(event)
);

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

๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ

const { interval } = Rx;
const { take } = RxOperators;

interval(1000).pipe(
    take(4)
)

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

ํ๋ฆ„โ€Š๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„๋ณ„๋กœ ์ •๋ ฌ๋œ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค. ์ด์ œ ํ•˜๋‚˜์˜ ์ž‘์—…์ด ์ฝ”๋“œ์˜ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์—์„œ ์—ฌ๋Ÿฌ ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ํŽธ๋ฆฌํ•ด์ง€๋Š”์ง€ ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์ŠคํŠธ๋ฆผ์„ ๊ตฌ๋…ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ•  ๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  RxJs ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

RxJS ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ๋ฐ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ์ž‘์—…ํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ธฐ๋ณธ ์œ ํ˜•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋ชฉํ•  ๋งŒํ•œ, ์—ฌ๋Ÿฌ ๋ณด์กฐ ์œ ํ˜•(๊ด€์ฐฐ์ž, ์Šค์ผ€์ค„๋Ÿฌ, ์ฃผ์ œ) ๋ฐ ์ปฌ๋ ‰์…˜๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฒคํŠธ ์ž‘์—…์„ ์œ„ํ•œ ์—ฐ์‚ฐ์ž(๋งคํ•‘, ํ•„ํ„ฐ, ์ถ•์†Œ, ๋ชจ๋“  JavaScript Array์™€ ์œ ์‚ฌํ•œ ๊ฒƒ).

์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์„ ์ดํ•ดํ•ด ๋ด…์‹œ๋‹ค.

๊ด€์ฐฐ ๊ฐ€๋Šฅ, ๊ด€์ฐฐ์ž, ์ƒ์‚ฐ์ž

Observable์€ ์šฐ๋ฆฌ๊ฐ€ ์‚ดํŽด๋ณผ ์ฒซ ๋ฒˆ์งธ ๊ธฐ๋ณธ ์œ ํ˜•์ž…๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค์—๋Š” RxJ ๊ตฌํ˜„์˜ ์ฃผ์š” ๋ถ€๋ถ„์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ตฌ๋… ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ŠคํŠธ๋ฆผ๊ณผ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

Observable์€ ์†Œ์œ„ ์—…๋ฐ์ดํŠธ ์ƒ์„ฑ์„ ์œ„ํ•œ ๋„์šฐ๋ฏธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๊ด€์ฐฐ์ž. Observer์˜ ๊ฐ’ ์†Œ์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ƒ์‚ฐ์ž. ์ด๋Š” ๋ฐฐ์—ด, ๋ฐ˜๋ณต์ž, ์›น ์†Œ์ผ“, ์ผ์ข…์˜ ์ด๋ฒคํŠธ ๋“ฑ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Observable์€ Producer์™€ Observer ์‚ฌ์ด์˜ ์ง€ํœ˜์ž๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Observable์€ ์„ธ ๊ฐ€์ง€ ์œ ํ˜•์˜ Observer ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹ค์Œ โ€“ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ
  • error โ€“ ์˜ˆ์™ธ๋กœ ์ธํ•ด ์‹œํ€€์Šค๊ฐ€ โ€‹โ€‹์ข…๋ฃŒ๋œ ๊ฒฝ์šฐ ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๋Š” ๋˜ํ•œ ์‹œํ€€์Šค์˜ ์™„๋ฃŒ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ์™„๋ฃŒ โ€” ์‹œํ€€์Šค ์™„๋ฃŒ์— ๋Œ€ํ•œ ์‹ ํ˜ธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋” ์ด์ƒ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋ฐ๋ชจ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์ฒ˜์Œ์—๋Š” 1, 2, 3, 1์ดˆ ์ดํ›„์˜ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 4๊ฐœ๋ฅผ ์–ป๊ณ  ์ŠคํŠธ๋ฆผ์„ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ํฐ ์†Œ๋ฆฌ๋กœ ์ƒ๊ฐํ•˜๊ธฐ

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์“ฐ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ทธ๊ฒƒ์„ ๋งํ•˜๋Š” ๊ฒƒ์ด ๋” ํฅ๋ฏธ๋กญ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ๐Ÿ˜€

๊ตฌ๋…

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

์ŠคํŠธ๋ฆผ ์œ ํ˜•

๋œจ๊ฑฐ์šด
๊ฐ๊ธฐ

์ƒ์‚ฐ์ž๋Š” ๊ด€์ฐฐ ๊ฐ€๋Šฅ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
์ƒ์‚ฐ์ž๋Š” Observable ๋‚ด๋ถ€์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

Observable์ด ์ƒ์„ฑ๋  ๋•Œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
๋ฐ์ดํ„ฐ๋Š” ๊ตฌ๋… ์‹œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

๊ตฌ๋… ์ทจ์†Œ๋ฅผ ์œ„ํ•œ ์ถ”๊ฐ€ ๋…ผ๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
์Šค๋ ˆ๋“œ๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

์ผ๋Œ€๋‹ค ๊ด€๊ณ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์ผ๋Œ€์ผ ๊ด€๊ณ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ตฌ๋…์€ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.
๊ตฌ๋…์€ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค.

๊ตฌ๋…ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ƒˆ ๊ตฌ๋…์— ๋Œ€ํ•œ ๋ชจ๋“  ์ŠคํŠธ๋ฆผ ๊ฐ’์„ ์žฌ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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

์†Œ์œ„ ๋”ฐ๋œปํ•œ ํ๋ฆ„๋„ ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. (์ด ์ •์˜๋Š” ๊ทนํžˆ ๋“œ๋ฌผ๊ฒŒ ์™ธ๊ตญ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ๋งŒ ์ ‘ํ–ˆ์Šต๋‹ˆ๋‹ค.) ์ด๊ฒƒ์€ ์ฐจ๊ฐ€์šด ํ๋ฆ„์—์„œ ๋œจ๊ฑฐ์šด ํ๋ฆ„์œผ๋กœ ์ „ํ™˜๋˜๋Š” ํ๋ฆ„์ž…๋‹ˆ๋‹ค. ์งˆ๋ฌธ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค-์–ด๋””์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?) ์—ฐ์Šต์—์„œ ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ €๋Š” Angular์™€ ํ•จ๊ป˜ ์ผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Š” rxjs๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๋ ค๋ฉด ์ฝœ๋“œ ์Šค๋ ˆ๋“œ๋ฅผ ์˜ˆ์ƒํ•˜๊ณ  asyncPipe๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์—์„œ ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ดํ”„๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜๊ณ  ์ฝœ๋“œ ์ŠคํŠธ๋ฆผ์˜ ์ •์˜๋กœ ๋Œ์•„๊ฐ€๋ฉด ๊ฐ ํŒŒ์ดํ”„๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋Š” ์•„๋ฌด๋ฆฌ ๋งํ•ด๋„ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฝœ๋“œ ์ŠคํŠธ๋ฆผ์„ ๋”ฐ๋œปํ•œ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ์š”์ฒญ์ด ํ•œ ๋ฒˆ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ํ๋ฆ„ ์œ ํ˜•์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ์ดˆ๋ณด์ž์—๊ฒŒ๋Š” ์ƒ๋‹นํžˆ ์–ด๋ ต์ง€๋งŒ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์—ฐ์‚ฐ์ž

return this.http.get(`${environment.apiUrl}/${this.apiUrl}/trade_companies`)
    .pipe(
        tap(({ data }: TradeCompanyList) => this.companies$$.next(cloneDeep(data))),
        map(({ data }: TradeCompanyList) => data)
    );

์šด์˜์ž๋Š” ์ŠคํŠธ๋ฆผ ์ž‘์—… ๋Šฅ๋ ฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Observable์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ธ๊ธฐ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€๋ฅผ ์‚ดํŽด๋ณด๊ณ , ์šด์˜์ž์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์œ ์šฉํ•œ ์ •๋ณด์— ์žˆ๋Š” ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฐ์‚ฐ์ž - ์ค‘

๋ณด์กฐ ์—ฐ์‚ฐ์ž๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ Observable์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์—ฐ์‚ฐ์ž - ํ•„ํ„ฐ

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

ํ•„ํ„ฐ ์—ฐ์‚ฐ์ž๋Š” ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ์ŠคํŠธ๋ฆผ ์‹ ํ˜ธ๋ฅผ ํ•„ํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ž๊ฐ€ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋” ์ด์ƒ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

์šด์˜์ž - ๋ฐ›์•„

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

take โ€” ์ด๋ฏธํ„ฐ ์ˆ˜์˜ ๊ฐ’์„ ์ทจํ•œ ํ›„ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

์—ฐ์‚ฐ์ž - debounceTime

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

debounceTime - ์ถœ๋ ฅ ์‚ฌ์ด์— ์ง€์ •๋œ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ ๋‚ด์— ์†ํ•˜๋Š” ๋ฐฉ์ถœ๋œ ๊ฐ’์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์ด ๊ฒฝ๊ณผํ•œ ํ›„ ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค.

const { Observable } = Rx;
const { debounceTime, take } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  observer.next(i++);
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1000ะผั
  setInterval(() => {
    observer.next(i++)
  }, 1000);

 // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1500ะผั
  setInterval(() => {
    observer.next(i++)
  }, 1500);
}).pipe(
  debounceTime(700),  // ะžะถะธะดะฐะตะผ 700ะผั ะทะฝะฐั‡ะตะฝะธั ะฟั€ะตะถะดะต ั‡ะตะผ ะพะฑั€ะฐะฑะพั‚ะฐั‚ัŒ
  take(3)
);  

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์—ฐ์‚ฐ์ž - takeWhile

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

takeWhile์ด false๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ๊นŒ์ง€ ๊ฐ’์„ ๋‚ด๋ณด๋‚ธ ํ›„ ์Šค๋ ˆ๋“œ์—์„œ ๊ตฌ๋…์„ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค.

const { Observable } = Rx;
const { debounceTime, takeWhile } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  observer.next(i++);
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1000ะผั
  setInterval(() => {
    observer.next(i++)
  }, 1000);
}).pipe(
  takeWhile( producer =>  producer < 5 )
);  

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์—ฐ์‚ฐ์ž - ๊ฒฐํ•ฉ์ตœ์‹ 

CombineLatest ์—ฐ์‚ฐ์ž๋Š” promise.all๊ณผ ๋‹ค์†Œ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ํ•˜๋‚˜๋กœ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ ๋ฐฉ์ถœ์„ ์ˆ˜ํ–‰ํ•œ ํ›„ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๊ฐ ์Šค๋ ˆ๋“œ์—์„œ ์ตœ์‹  ๊ฐ’์„ ์–ป์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ณ‘ํ•ฉ๋œ ์ŠคํŠธ๋ฆผ์—์„œ ๋ฐฉ์ถœ๋œ ํ›„์—๋Š” ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

const { combineLatest, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1000ะผั
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
});

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 750ะผั
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
});

combineLatest(observer_1, observer_2).pipe(take(5));

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์—ฐ์‚ฐ์ž - zip

Zip - ๊ฐ ์Šค๋ ˆ๋“œ์˜ ๊ฐ’์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐฐ์—ด์„ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์ด ์–ด๋–ค ์Šค๋ ˆ๋“œ์—์„œ๋„ ๋‚˜์˜ค์ง€ ์•Š์œผ๋ฉด ๊ทธ๋ฃน์ด ํ˜•์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

const { zip, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1000ะผั
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
});

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 750
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
});

const observer_3 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 500
  setInterval(() => {
    observer.next('c: ' + i++);
  }, 500);
});

zip(observer_1, observer_2, observer_3).pipe(take(5));

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์—ฐ์‚ฐ์ž - forkJoin

forkJoin๋„ ์Šค๋ ˆ๋“œ๋ฅผ ์กฐ์ธํ•˜์ง€๋งŒ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๋งŒ ๊ฐ’์„ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

const { forkJoin, Observable } = Rx;
const { take } = RxOperators;

const observer_1 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1000ะผั
  setInterval(() => {
    observer.next('a: ' + i++);
  }, 1000);
}).pipe(take(3));

const observer_2 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 750
  setInterval(() => {
    observer.next('b: ' + i++);
  }, 750);
}).pipe(take(5));

const observer_3 = Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 500
  setInterval(() => {
    observer.next('c: ' + i++);
  }, 500);
}).pipe(take(4));

forkJoin(observer_1, observer_2, observer_3);

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์—ฐ์‚ฐ์ž - ์ง€๋„

๋งต ๋ณ€ํ™˜ ์—ฐ์‚ฐ์ž๋Š” ์ด๋ฏธํ„ฐ ๊ฐ’์„ ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

const {  Observable } = Rx;
const { take, map } = RxOperators;

Observable.create((observer) => {
  let i = 1;
  // ะ˜ัะฟัƒัะบะฐะตะผ ะทะฝะฐั‡ะตะฝะธะต ั€ะฐะท ะฒ 1000ะผั
  setInterval(() => {
    observer.next(i++);
  }, 1000);
}).pipe(
  map(x => x * 10),
  take(3)
);

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์šด์˜์ž - ๊ณต์œ , ํƒญ

ํƒญ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ€์ž‘์šฉ, ์ฆ‰ ์‹œํ€€์Šค์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณต์œ  ์œ ํ‹ธ๋ฆฌํ‹ฐ ์šด์˜์ž๋Š” ์ฝœ๋“œ ์ŠคํŠธ๋ฆผ์„ ํ•ซ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์ฝœ๋ฐฑ, Promise, RxJs)

์šด์˜์ž์™€์˜ ์ž‘์—…์€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ฃผ์ œ๋กœ ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

ํฐ ์†Œ๋ฆฌ๋กœ ์ƒ๊ฐํ•˜๊ธฐ

๊ทธ๋ฆฌ๊ณ  ์ฐจ๋ฅผ ๋งˆ์‹œ๋Ÿฌ ๊ฐ”์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๋Ÿฌํ•œ ์˜ˆ์— ์ง€์ณค์Šต๋‹ˆ๋‹ค ๐Ÿ˜€

๋Œ€์ƒ๊ฐ€์กฑ

์ฃผ์ œ๊ตฐ์€ ๋œจ๊ฑฐ์šด ํ๋ฆ„์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํด๋ž˜์Šค๋Š” ๊ด€์ฐฐ ๊ฐ€๋Šฅ ๋ฐ ๊ด€์ฐฐ์ž ์—ญํ• ์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•˜๋Š” ์ผ์ข…์˜ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ์ž…๋‹ˆ๋‹ค. ์ฃผ์ œ๊ฐ€ ํ•ซ์Šค๋ ˆ๋“œ์ด๋ฏ€๋กœ ๊ตฌ๋…์„ ์ทจ์†Œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋‹ค์Œ โ€“ ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ „์†ก
  • error - ์˜ค๋ฅ˜ ๋ฐ ์Šค๋ ˆ๋“œ ์ข…๋ฃŒ
  • ์™„๋ฃŒ โ€“ ์Šค๋ ˆ๋“œ ์™„๋ฃŒ
  • ๊ตฌ๋… โ€“ ์ŠคํŠธ๋ฆผ ๊ตฌ๋…
  • unsubscribe โ€“ ์ŠคํŠธ๋ฆผ ๊ตฌ๋…์„ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค.
  • asObservable โ€“ ๊ด€์ฐฐ์ž๋กœ ๋ณ€ํ™˜
  • toPromise โ€“ ์•ฝ์†์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

๊ณผ๋ชฉ์€ 4 5๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํฐ ์†Œ๋ฆฌ๋กœ ์ƒ๊ฐํ•˜๊ธฐ

์ŠคํŠธ๋ฆผ์—์„œ 4๋ช…์ด ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ์•Œ๊ณ  ๋ณด๋‹ˆ ํ•œ ๋ช…์ด ๋” ์ถ”๊ฐ€๋œ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์ด ๋งํ–ˆ๋“ฏ์ด ์‚ด๊ณ  ๋ฐฐ์šฐ์‹ญ์‹œ์˜ค.

๊ฐ„๋‹จํ•œ ์ฃผ์ œ new Subject()โ€“ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์œ ํ˜•์˜ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ๋… ํ›„ ๋ฐ›์€ ๊ฐ’๋งŒ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

ํ–‰๋™ ์ฃผ์ œ new BehaviorSubject( defaultData<T> ) โ€“ ์ œ ์ƒ๊ฐ์—๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์œ ํ˜•์˜ ์ฃผ์ œ์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ์€ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๋… ์‹œ ์ „์†ก๋˜๋Š” ์ตœ์‹  ํ˜ธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ญ์ƒ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค์—๋Š” ์ŠคํŠธ๋ฆผ์˜ ํ˜„์žฌ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์œ ์šฉํ•œ ๊ฐ’ ๋ฉ”์„œ๋“œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์žฌ์ƒ์ฃผ์ œ new ReplaySubject(bufferSize?: number, windowTime?: number) โ€” ์ž…๋ ฅ์€ ์„ ํƒ์ ์œผ๋กœ ์ž์ฒด์ ์œผ๋กœ ์ €์žฅํ•  ๊ฐ’์˜ ๋ฒ„ํผ ํฌ๊ธฐ๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ทจํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ์‹œ๊ฐ„์„ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ์ฃผ์ œ new AsyncSubject() โ€” ๊ตฌ๋… ์‹œ ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฉฐ ์™„๋ฃŒ๋  ๋•Œ๋งŒ ๊ฐ’์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ŠคํŠธ๋ฆผ์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’๋งŒ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์›น์†Œ์ผ“์ฃผ์ œ new WebSocketSubject(urlConfigOrSource: string | WebSocketSubjectConfig<T> | Observable<T>, destination?: Observer<T>) โ€” ๋ฌธ์„œ์—๋Š” ๊ทธ์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ์—†์œผ๋ฉฐ ์ €๋Š” ์ฒ˜์Œ์œผ๋กœ ๊ทธ๋ฅผ ๋ต™์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ๋‹ค๋ฉด ์ ์–ด์ฃผ์‹œ๋ฉด ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ํœด. ์ž, ์˜ค๋Š˜ ๋ง์”€๋“œ๋ฆฌ๊ณ  ์‹ถ์€ ๋‚ด์šฉ์€ ๋ชจ๋‘ ๋‹ค ๋‹ค๋ฃจ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ •๋ณด๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์œ ์šฉํ•œ ์ •๋ณด ํƒญ์—์„œ ์ฐธ๊ณ ๋ฌธํ—Œ ๋ชฉ๋ก์„ ์ง์ ‘ ์ฝ์–ด๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ์šฉํ•œ ์ •๋ณด

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€