[JS] chapter19. ๋น๋๊ธฐ1 - java script
๐ ๋น๋๊ธฐ
- ๋๊ธฐ(synchronous)
๋๊ธฐ ์ฒ๋ฆฌ๋, ํน์ ์ฝ๋์ ์คํ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ณ ๋ ํ ๋ค์ ์ฝ๋๋ฅผ ์ํํ๋ ๊ฒ
- ๋น๋๊ธฐ(asynchronous)
๋น๋๊ธฐ ์ฒ๋ฆฌ๋, ํน์ ์ฝ๋์ ์คํ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค์ ์ฝ๋๋ฅผ ์ํํ๋ ๊ฒ
js๋ ์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ ๋์ ์ธ์ด๋ผ์ ๋๊ธฐ์ ์๋์ด์ง๋ง ํ๊ฒฝ(๋ฐํ์)์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋์์ฃผ๊ธฐ ๋๋ฌธ์
๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ํ ๊ฐ๋ฅํ๋ค.
๋น๋๊ธฐ๋ ์์๋๋ก ์๋ํ์ง ์๋ ๊ฒ์ ๊ธฐ์ตํ์!
โฑ ํ์ด๋จธ ๊ด๋ จ API
๋น๋๊ธฐ ์ฒซ๋ฒ์งธ ๋จ๊ณ ํ์ด๋จธ ๊ด๋ จ API
setTimeout(callback, millisecond)
์ผ์ ์๊ฐ ํ์ ํจ์๋ฅผ ์คํ
- ๋งค๊ฐ๋ณ์(parameter): ์คํํ ์ฝ๋ฐฑ ํจ์, ์ฝ๋ฐฑ ํจ์ ์คํ ์ ๊ธฐ๋ค๋ ค์ผ ํ ์๊ฐ (๋ฐ๋ฆฌ์ด)
- return ๊ฐ: ์์์ ํ์ด๋จธ ID
setTimeout(function () {
console.log('1์ด ํ ์คํ');
}, 1000);
// 123
clearTimeout(timerId)
setTimeout ํ์ด๋จธ๋ฅผ ์ข ๋ฃ
- ๋งค๊ฐ๋ณ์(parameter): ํ์ด๋จธ ID
- return ๊ฐ: ์์
const timer = setTimeout(function () {
console.log('10์ด ํ ์คํ');
}, 10000);
clearTimeout(timer);
// setTimeout์ด ์ข
๋ฃ๋จ.
setInterval(callback, millisecond)
์ผ์ ์๊ฐ์ ๊ฐ๊ฒฉ์ ๊ฐ์ง๊ณ ํจ์๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ์คํ
- ๋งค๊ฐ๋ณ์(parameter): ์คํํ ์ฝ๋ฐฑ ํจ์, ๋ฐ๋ณต์ ์ผ๋ก ํจ์๋ฅผ ์คํ์ํค๊ธฐ ์ํ ์๊ฐ ๊ฐ๊ฒฉ (๋ฐ๋ฆฌ์ด)
- return ๊ฐ: ์์์ ํ์ด๋จธ ID
setInterval(function () {
console.log('1์ด๋ง๋ค ์คํ');
}, 1000);
// 345
clearInterval(timerId)
setInterval ํ์ด๋จธ๋ฅผ ์ข ๋ฃ
- ๋งค๊ฐ๋ณ์: ํ์ด๋จธ ID
- return ๊ฐ: ์์
const timer = setInterval(function () {
console.log('1์ด๋ง๋ค ์คํ');
}, 1000);
clearInterval(timer);
// setInterval์ด ์ข
๋ฃ๋จ.
๋น๋๊ธฐ๋ก ์๋ํ๋ ์ฝ๋๋ฅผ ์ ์ดํ ์ ์๋ ๋ฐฉ๋ฒ1 - ์ฝ๋ฐฑํจ์
์ ์ดํ์ง ์์ ์ฝ๋
// ํฐ๋ฏธ๋์ `node index.js`๋ฅผ ์
๋ ฅํ์ฌ ๋น๋๊ธฐ ์ฝ๋๊ฐ ์๋ํ๋ ์์๋ฅผ ํ์ธํด๋ณด์ธ์.
const printString = (string) => {
setTimeout(function () {
console.log(string);
}, Math.floor(Math.random() * 100) + 1);
};
const printAll = () => {
printString('A');
printString('B');
printString('C');
};
printAll();
console.log(`์๋์ ๊ฐ์ด ๋น๋๊ธฐ ์ฝ๋๋ ์์๋ฅผ ๋ณด์ฅํ์ง ์์ต๋๋ค!`);
์ ์ด๋ ์ฝ๋
์ฃผ์์ฌํญ
๐ ์ฝ๋๊ฐ ๊ธธ์ด์ง๊ณ ๋ณต์กํ ์๋ก ๊ฐ๋ ์ฑ์ ๋ฎ์์ง๋ ๋จ์ ์ด ์๋ค.
// ํฐ๋ฏธ๋์ `node index.js`๋ฅผ ์
๋ ฅํ์ฌ ๋น๋๊ธฐ ์ฝ๋๊ฐ ์๋ํ๋ ์์๋ฅผ ํ์ธํด๋ณด์ธ์.
const printString = (string, callback) => {
setTimeout(function () {
console.log(string);
callback(); // ์ฝ๋ฐฑํจ์๋ฅผ ํตํด ์์๋ฅผ ์ ์ดํ ์ ์๋ค
}, Math.floor(Math.random() * 100) + 1);
};
const printAll = () => {
printString('A', () => {
printString('B', () => {
printString('C', () => {});
});
});
};
printAll();
console.log(
`์๋์ ๊ฐ์ด Callback ํจ์๋ฅผ ํตํด ๋น๋๊ธฐ ์ฝ๋์ ์์๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค!`
);
๋น๋๊ธฐ๋ก ์๋ํ๋ ์ฝ๋๋ฅผ ์ ์ดํ ์ ์๋ ๋ฐฉ๋ฒ2 - Promise
new Promise
Promise๋ class์ด๊ธฐ ๋๋ฌธ์ new ํค์๋๋ฅผ ํตํด Promise ๊ฐ์ฒด๋ฅผ ์์ฑ
๋ํ Promise๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ ์ฝ๋ฐฑ ํจ์(executor)๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ฐ
์ด ์ฝ๋ฐฑ ํจ์๋ resolve, reject ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ
promise ๊ฐ์ฒด ์์ฑ -> resolve ํจ์ ํธ์ถ -> ์๋ฌ ๋ฐ์ ๊ฒฝ์ฐ reject ํจ์ ํธ์ถ
let promise = new Promise((resolve, reject) => {
// 1. ์ ์์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ ๊ฒฝ์ฐ
// resolve์ ์ธ์์ ๊ฐ์ ์ ๋ฌํ ์๋ ์์ต๋๋ค.
resolve(value);
// 2. ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ
// reject์ ์ธ์์ ์๋ฌ๋ฉ์ธ์ง๋ฅผ ์ ๋ฌํ ์๋ ์์ต๋๋ค.
reject(error);
});
promise ๊ฐ์ฒด ๋ด๋ถ ํ๋กํผํฐ
state : ๋๊ธฐ
result : undefined -> value -> error
then : .then ๋ฉ์๋ ์ ๊ทผ
let promise = new Promise((resolve, reject) => {
resolve("์ฑ๊ณต");
});
promise.then(value => {
console.log(value);
// "์ฑ๊ณต"
})
catch : ์๋ฌ ๋ฐ์์ reject ํจ์ ํธ์ถ
let promise = new Promise(function(resolve, reject) {
reject(new Error("์๋ฌ"))
});
promise.catch(error => {
console.log(error);
// Error: ์๋ฌ
})
finally : ์ ์ ์ฒ๋ฆฌ ์ฌ๋ถ ๊ด๊ณ ์์ด finally๋ฉ์๋๋ก ์ ๊ทผ
let promise = new Promise(function(resolve, reject) {
resolve("์ฑ๊ณต");
});
promise
.then(value => {
console.log(value);
// "์ฑ๊ณต"
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log("์ฑ๊ณต์ด๋ ์คํจ๋ ์๋!");
// "์ฑ๊ณต์ด๋ ์คํจ๋ ์๋!"
})
Promise chaining
Promise chaining๊ฐ ํ์ํ๋ ๊ฒฝ์ฐ๋ ๋น๋๊ธฐ ์์ ์ ์์ฐจ์ ์ผ๋ก ์งํํด์ผ ํ๋ ๊ฒฝ์ฐ
Promise chaining์ด ๊ฐ๋ฅํ ์ด์ ๋ .then, .catch, .finally ์ ๋ฉ์๋๋ค์ Promise๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ
.then์ ํตํด ์ฐ๊ฒฐํ ์ ์๊ณ , ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ .catch ๋ก ์ฒ๋ฆฌํ๋ฉด ๋๋ค
let promise = new Promise(function(resolve, reject) {
resolve('์ฑ๊ณต');
...
});
promise
.then((value) => {
console.log(value);
return '์ฑ๊ณต';
})
.then((value) => {
console.log(value);
return '์ฑ๊ณต';
})
.then((value) => {
console.log(value);
return '์ฑ๊ณต';
})
.catch((error) => {
console.log(error);
return '์คํจ';
})
.finally(() => {
console.log('์ฑ๊ณต์ด๋ ์คํจ๋ ์๋!');
});
Promise.all
Promise.all()์ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ๋์์ ์ฒ๋ฆฌํ๊ณ ์ถ์๋ ์ฌ์ฉ
const promiseOne = () => new Promise((resolve, reject) => setTimeout(() => resolve('1์ด'), 1000));
const promiseTwo = () => new Promise((resolve, reject) => setTimeout(() => resolve('2์ด'), 2000));
const promiseThree = () => new Promise((resolve, reject) => setTimeout(() => resolve('3์ด'), 3000));
๊ธฐ์กด Promise chaining์ promise.all๋ก๋ ํด๊ฒฐ ๊ฐ๋ฅ
// promise.all
Promise.all([promiseOne(), promiseTwo(), promiseThree()])
.then((value) => console.log(value))
// ['1์ด', '2์ด', '3์ด']
.catch((err) => console.log(err));
+ Promise.all()์ ํ๋๋ผ๋ ์๋ฌ๊ฐ ๋ฐ์ ํ๋ฉด ์ฆ์ ์ข ๋ฃ
ex) 1์ด ํ์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ณ error:1์ด ๋ฐํ๋ ํ๋ก๋ ์๋ x
Promise.all([
new Promise((resolve, reject) => setTimeout(() => reject(new Error('์๋ฌ1'))), 1000),
new Promise((resolve, reject) => setTimeout(() => reject(new Error('์๋ฌ2'))), 2000),
new Promise((resolve, reject) => setTimeout(() => reject(new Error('์๋ฌ3'))), 3000),
])
.then((value) => console.log(value))
.catch((err) => console.log(err));
// Error: ์๋ฌ1
Promise Hell
Promise๋ฅผ ํตํด ๋น๋๊ธฐ ์ฝ๋์ ์์๋ฅผ ์ ์ดํ ์ ์์ง๋ง Callback ํจ์์ ๊ฐ์ด ์ฝ๋๊ฐ ๊ธธ์ด์ง์๋ก ๋ณต์กํด์ง๊ณ
๊ฐ๋ ์ฑ์ด ๋ฎ์์ง๋ Promise Hell์ด ๋ฐ์ํ๋ ๋จ์ ์ด ์๋ค
const printString = (string) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(string);
}, Math.floor(Math.random() * 100) + 1);
});
};
const printAll = () => {
printString('A').then((value) => {
console.log(value);
printString('B').then((value) => {
console.log(value);
๐ช Async/Await (์ค์)
๋ณต์กํ promise ์ฝ๋ ๋์ ๊ฐ๊ฒฐํ๊ฒ ์์ฑ ๊ฐ๋ฅ
ํจ์ ์์ async ํค์๋๋ฅผ ์ฌ์ฉํ๊ณ async ํจ์ ๋ด์์๋ง await ํค์๋๋ฅผ ์ฌ์ฉ