'์ฝ์'์ ๋๋ค. ๋ฏธ๋์ ์ผ์ด๋ ์ผ์ ์ฝ์ํ๋ ๊ฒ์ผ๋ก
๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉ๋๋ ๊ฐ์ฒด์ ๋๋ค.
์ฌ๋ฟ ๊ฐ๋ฐ ๊ณผ์ ์์ ๋๊ธฐ, ๋น๋๊ธฐ๋ผ๋ ๋ง์ ๋ง์ด ๋ค์ด ๋ณด์์ง ์์๋์?
โ๏ธ ๋๊ธฐ
๋๊ธฐ๋ ์ง๋ ฌ์ ์ผ๋ก ์๋ํ๋ ๋ฐฉ์์ ๋๋ค.
โ๏ธ ๋น๋๊ธฐ
๋น๋๊ธฐ๋ ๋ณ๋ ฌ์ ์ผ๋ก ์๋ํ๋ ๋ฐฉ์์ ๋๋ค.
์ฌ๊ธฐ์ ๋ณด์ด๋ ๋๊ธฐ์ ๋น๋๊ธฐ์ ์ฐจ์ด์ ์ด ์์ต๋๋ค.
๋น๋๊ธฐ๋ ํน์ ์ฝ๋๊ฐ ๋๋ ๋ ๊น์ง ์ฝ๋์ ์คํ์ ๋ฉ์ถ์ง ์๊ณ ๋ค์ ์ฝ๋๋ฅผ ๋จผ์ ์คํํ๋ ๊ฒ์ด์ฃ .
ํ๋ฒ ์ฌ์ง์ ํตํด ๋น๊ตํด๋ณผ๊น์?
[ ์ถ์ฒ | What every programmer should know about Synchronous vs. Asynchronous Code]
์ผ์ชฝ ๊ทธ๋ํ๋ '๋น๋๊ธฐ'๋ก ์๋ํ๋ ๋ฐฉ์์
๋๋ค.
ํ๋ฒ์ ์ฌ๋ฌ Task(๋นจ๊ฐ, ๋ฏผํธ, ์๋ก ๋ง๋๊ทธ๋ํ)๊ฐ ๋์์ ๋ณ๋ ฌ์ ์ผ๋ก ์คํ๋๋ ๋ชจ์ต์ ๋ณด์
๋๋ค.
๋ฐ๋ฉด, ์ค๋ฅธ์ชฝ ์ฐจํธ๋ '๋๊ธฐ'์ ์ผ๋ก ์๋ํ๋ ๋ฐฉ์์
๋๋ค.
ํ๋์ Task๊ฐ ๋๋ ๋ ๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๋ค์ Task๊ฐ ์คํ๋๋ ๋ชจ์ต์ ๋ณผ ์ ์์ฃ .
์๊น ์์๋๋ก ๋นจ๊ฐ์ด ์คํ๋๊ณ ๋ฏผํธ๊ฐ ์คํ๋๊ณ ๋
ธ๋์ด ์คํ๋ฉ๋๋ค.
๊ทธ๋ ๊ธฐ์ ์ด ์คํ ์๊ฐ์ผ๋ก ๋ฐ์ง์๋ฉด '๋๊ธฐ' ๋ฐฉ์์ด ๋ ๋๋ฆฌ๊ฒ ๋ฉ๋๋ค.
NVIDIA GPU์ CPU์ฐจ์ด
ํด๋น ๋งํฌ๋ NVIDIA์์ CPU,GPU๋ฅผ ์๊ฐํ๋ ์์์ ๋๋ค.
์ ๋ ํด๋น ์์์ ๋ณด๋ฉด์ ๋๊ธฐ(CPU) ๋น๋๊ธฐ(GPU)๋ฅผ ์ดํดํ๋๋ฐ ๋์์ ์ป์์ต๋๋ค.
ํ์ํ์ ๋ถ์ ์์ฒญํด์ฃผ์๋ฉด ํ๋ฒ ๋ด์ฃผ์ธ์ :) (๋งค์ฐ ์งง์ต๋๋ค ๐)
์ ๊ทธ๋ผ ๋ค์ ๋์๊ฐ๋ณด์ฃ
๋๊ธฐ๋ ์ง๋ ฌ์ ์ผ๋ก Task๋ฅผ ์ํํ๋ ๋ฐฉ์์ ๋๋ค.
์ฆ, ์์ฒญ์ ๋ณด๋ธ ํ ์๋ต์ ๋ฐ์์ผ์ง๋ง ๋ค์ ๋์์ด ์ด๋ฃจ์ด์ง๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์์ Task๊ฐ ์ฒ๋ฆฌ๋์ด์ผ ๋๋จธ์ง ๋ค์ Task๋ค์ด ์คํ ํ ์ ์๋ ๊ฒ๋๋ค.
์ถ์ฒ | poiemaweb
๋น๋๊ธฐ๋ ๋ณ๋ ฌ์ ์ผ๋ก Task๋ฅผ ์ํํ๋ ๋ฐฉ์์
๋๋ค.
Task๊ฐ ์ข
๋ฃ๋์ง ์์ ์ํ๋ผ ํ๋๋ผ๋ ๋๊ธฐํ์ง ์๊ณ ์ฆ์ ๋ค์ Task๋ฅผ ์คํํ๋ค.
์ถ์ฒ | poiemaweb
- ์๋ฅผ ๋ค์ด ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ ํ๋ฉด์ ํ์ํ๊ณ ์ ํ ๋ ์๋ฒ์ Task๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ฒ๋ฉ๋๋ค.
- ์ดํ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๊ฐ ์๋ต๋ ๋๊น์ง ๋๊ธฐํ์ง ์๊ณ (Non-Blocking) ์ฆ์ ๋ค์ Task๋ฅผ ์ํํ๊ฒ ๋ฉ๋๋ค.
- ์ดํ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๊ฐ ์๋ต๋๋ฉด ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ํํ Task๋ฅผ ๊ณ์ํด ์ํํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์ ๋๋ถ๋ถ์ DOM ์ด๋ฒคํธ์ Timer ํจ์(setTimeout, setInterval), Ajax ์์ฒญ์ ๋น๋๊ธฐ์ ์ฒ๋ฆฌ ๋ชจ๋ธ๋ก ๋์ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋ฒํ๊ฒ ์ฌ์ฉ๋๋ ๋น๋๊ธฐ์ ์ฒ๋ฆฌ ๋ชจ๋ธ์ ์์ฒญ์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ์ฌ ๋ค๋ฅธ ์์ฒญ์ด ๋ธ๋กํน(blocking, ์์ ์ค๋จ)๋์ง ์์ต๋๋ค.
ํ์ง๋ง ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ์ฝ๋ฐฑ ํจํด์ ์ฌ์ฉํ๋ฉด ์ฒ๋ฆฌ ์์๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ฐ์ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ค์คํ
(nesting, ์ค์ฒฉ)๋์ด ๋ณต์ก๋๊ฐ ๋์์ง๋ ์ฝ๋ฐฑ ํฌ(Callback Hell)์ด ๋ฐ์ํ๋ ๋จ์ ์ด ์์ต๋๋ค.
์ฝ๋ฐฑ ํฌ์ ๊ฐ๋
์ฑ์ ๋์๊ฒ ํ๋ฉฐ ์ค์๋ฅผ ์ ๋ฐํ๋ ์์ธ์ด ๋ฉ๋๋ค.
ํ๋จ ์ฝ๋๋ ์ฝ๋ฐฑ ํฌ์ด ๋ฐ์ํ๋ ์ ํ์ ์ธ ์ฌ๋ก์
๋๋ค.
step1(function(value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
step5(value4, function(value5) {
// value5๋ฅผ ์ฌ์ฉํ๋ ์ฒ๋ฆฌ
});
});
});
});
});
๋๊ธฐ ๋น๋๊ธฐ์ ๋ํ ์ง์์ ์ฑ์ ์ผ๋ ํด๋น ๊ธ์ ์ค์ฌ์ธ Promise๋ก ๋์์๋ณด์
๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉ๋๋ ๊ฐ์ฒด(Promise ๊ฐ์ฒด)
โจ ํน์ง
- Promise๋ ๋ฏธ๋์ ์๋ฃ๋ ์์ ์ ๋ํ๋ด๋ ๊ฐ์ฒด์ ๋๋ค.
- ์์ ์ด ์๋ฃ๋๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ(resolve)ํ๊ฑฐ๋, ์์ ์ด ์คํจํ๋ฉด ์๋ฌ๋ฅผ ๋ฐํ(reject)ํฉ๋๋ค.
- ์ฃผ๋ก .then()๊ณผ .catch()๊ตฌ๋ฌธ์ ์ฌ์ฉํด ์ฑ๊ณต ์์ ์คํจ ์์์ฒ๋ฆฌ๋ฅผ ๊ตฌ๋ถํฉ๋๋ค.
์ฝ๋๋ฅผ ๋ณด๋ฉฐ ๋ฌด์จ ๋ง์ธ์ง ๋ณด๋๋กํ์ฃ
ํ๋จ ์ฝ๋๋ Promise๊ฐ์ฒด๋ฅผ ์ด์ฉํด hello๋ฅผ ์
๋ ฅ์
console์ ์ ์์ ์ผ๋ก ์ฑ๊ณต, ์คํจ ๋ด์ฉ์ด ๋ฐํ ๋๋์ง ํ์ธํ๊ณ ์ํ ์ฝ๋์
๋๋ค.
//Promise๋ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ์์ฑ์(new)๋ฅผ ์ด์ฉํด ๋ง๋ค๊ฒ๋ฉ๋๋ค.
const myPromise = new Promise((resolve, reject)=>{
//Promise ๊ฐ์ฒด ์์ฑ์ ์ธ์๋ก call back ํจ์๋ฅผ ๋ฃ์ ์ ์์ต๋๋ค.
//์ด๋ฌํ call back ํจ์ ์์์ ๋น๋๊ธฐ ์์
์ ์ฒ๋ฆฌํฉ๋๋ค.
//์ด๋ค ์์
์ ์งํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ค~ ํ๊ณ ์ฝ์ํ ๊ฒ ์ด์ฃ
//myPromise๋ฅผ ํตํด ์ฝ์์ ๊ฐ์ฒด๋ฅผ ๋ฐ์ต๋๋ค.
setTimeout(()=>{
const text = prompt(`"hello"๋ฅผ ์
๋ ฅํ๋ฉด ์ ๋ฌผ์ ์ค๊ป`);
if(text === "hello"){
resolve( '๐ป'); //์น์ธ
}else{
reject('error message') //์คํจ
}
}, 2000); //2์ด ํ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ
});
myPromise
.then((result)=>{
console.log('result',result);
})
.catch(()=>{
console.log("err:", err);
})
.finally(()=>{
console.log("finally");
})
์ฝ๋๋ฅผ ์์ธํ ์ดํด๋ด ์๋ค.
Promise ๊ฐ์ฒด ์์ฑ์(์์ฑ์ new) ์ธ์๋ก call back ํจ์๋ฅผ ์์ ๋ฃ์ ์ ์์ต๋๋ค.
//myPromise๋ฅผ ํตํด ์ฝ์์ ๊ฐ์ฒด๋ฅผ ๋ฐ์ต๋๋ค. const myPromise = new Promise(()=>{ //ํด๋น ๊ณต๊ฐ์๋ callback(๋น๋๊ธฐ) ํจ์๋ฅผ ์ง์ด ๋ฃ์ผ๋ฉด ๋ฉ๋๋ค. //๊ทธ๋์ ์๋จ ์ฝ๋์์๋ setTimeout(๋น๋๊ธฐ)์ด ์ฌ์ฉ๋๊ฒ์ ๋๋ค. }
์ด๋ฌํ call back ํจ์ ์์์ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๊ฒ๋๋๊ฒ๋๋ค.
์ฆ "์ด๋ค ์์ ์ ์งํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ค~" ํ๊ณ ์ฝ์(Promise)ํ ๊ฒ ์ด์ฃ
๋๋ฒ์งธ ํน์ง์์
- ์์ ์ด ์๋ฃ๋๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ(resolve)
- ์์ ์ด ์คํจํ๋ฉด ์๋ฌ๋ฅผ ๋ฐํ(reject)
์ด๋ ๊ฒ ์๊ฐ๋๋ ธ์ต๋๋ค.// Promise ๊ฐ์ฒด์ ์์ฑ const promise = new Promise((resolve, reject) => {// resolve, reject ์ฌ์ฉ์ ์ ์ธ // ๋น๋๊ธฐ ์์ ์ ์ํํ๋ค. setTimeout(()=>{ const text = prompt(`"hello"๋ฅผ ์ ๋ ฅํ๋ฉด ์ ๋ฌผ์ ์ค๊ป`);//prompt๋ก ํ ์คํธ ์ ๋ฌํด์ค if(text === "hello"){ resolve( '๐ป'); //์น์ธ์ ์ถ๋ ฅ }else{ reject('error message') //์คํจ์ ์ถ๋ ฅ } }, 2000); //2์ด ํ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ } });
ํด๋น ์ฝ๋๋ฅผ ๋ณด๋ฉด setTimeout์ผ๋ก ๋น๋๊ธฐ ์์ ์ ์คํํ๊ฒ๋๊ณ
prompt์ ์ํ๋ ๊ฐ์ ์ ๋ ฅํฉ๋๋ค.
hello๋ฅผ ์ ๋ ฅ์ ๐ป์ ์์ ์ผ๋ก ์ถ๋ ฅ์ด๋๋ ๋ชจ์ต์ ๋ณผ ์ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ค๋ฅธ ๊ฐ์ ๋ฃ์ด๋ณด๊ฒ ์ต๋๋ค.
์ด๋ ๊ฒ ์๋ฌ๋ฅผ ์ถ๋ ฅํ๋ ๋ชจ์ต์ ๋ณผ ์ ์์ต๋๋ค.
์ด๋ Promise๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณต(fulfilled)ํ์๋์ง ๋๋ ์คํจ(rejected)ํ์๋์ง ๋ฑ์ ์ํ(state) ์ ๋ณด๋ฅผ ๊ฐ์ง๊ฒ๋ฉ๋๋ค.
ํ๋จ ๋ถ๋ถ์ ๋น๋๊ธฐ ํจ์๊ฐ ์ ์์ ์ผ๋ก ์๋ํ์๋
.then() , .catch()์ด๋ผ๋ ๋ฉ์๋์ callbackํจ์๋ก ๋ด์์ ํ์ธ์ด ๊ฐ๋ฅํฉ๋๋ค.
then()
๋น๋๊ธฐ ํจ์ ๋ด์์ Promise ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ทธ ๋ด๋ถ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค.
์ด๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์ฑ๊ณตํ๋ฉด resolve ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
์ด๋ resolve ๋ฉ์๋์ ์ธ์๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌ ํ๋๋ฐ, ์ด ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ Promise ๊ฐ์ฒด์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ก ์ ๋ฌ๋ฉ๋๋ค..
catch()
๋ง์ฝ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์คํจํ๋ฉด reject ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
์ด๋ reject ๋ฉ์๋์ ์ธ์๋ก ์๋ฌ ๋ฉ์์ง๋ฅผ ์ ๋ฌํฉ๋๋ค.
์ด ์๋ฌ ๋ฉ์์ง๋ Promise ๊ฐ์ฒด์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ก ์ ๋ฌ๋๋ฉฐ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์๋ ๋ํ์ ์ผ๋ก then(Promise ๋ฐํ)๊ณผ catch(์์ธ)๊ฐ ์์ต๋๋ค.
myPromise
.then((result)=>{
console.log('result',result);
})
.catch(()=>{
console.log("err:", err);
})
.finally(()=>{
console.log("finally");
})
๋น๋๊ธฐ ํจ์์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ๋ค๋ฅธ ๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ์์ต๋๋ค.
์ด๋ ํจ์์ ํธ์ถ์ด ์ค์ฒฉ(nesting)์ด ๋์ด ๋ณต์ก๋๊ฐ ๋์์ง๋ ์ฝ๋ฐฑ ํฌ์ด ๋ฐ์ํ๊ฒ๋ฉ๋๋ค.
ํ๋ก๋ฏธ์ค๋ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์ธ then์ด๋ catch๋ก ๋ฉ์๋๋ฅผ ์ฒด์ด๋(chainning)ํ์ฌ ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค๋ฅผ ์ฐ๊ฒฐํ์ฌ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฝ๋ฐฑ ํฌ์ ํด๊ฒฐํ ์์์ต๋๋ค.
๋ฐ๋ผ์, then ๋ฉ์๋๊ฐ Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋๋ก ํ๋ฉด(then ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก Promise๋ฅผ ๋ฐํํ๋ค.) ์ฌ๋ฌ ๊ฐ์ ํ๋ก๋ฏธ์ค๋ฅผ ์ฐ๊ฒฐํ์ฌ ์ฌ์ฉํ ์ ์์ต๋๋ค.