โ์ฐ๋ฆฌ๊ฐ ์ ๋ฌํ ํจ์๋ฅผ ๋์ค์ ๋ถ๋ฌ์คโ
CallBack
โ์ฐ๋ฆฌ๊ฐ ์ ๋ฌํ ํจ์๋ฅผ ๋์ค์ ๋ถ๋ฌ์คโ
1. ๋๊ธฐ์ ๋น๋๊ธฐ
JavaScript is asynchronous. JS๋ ๋๊ธฐ์ ์ด๋ค
ํธ์ด์คํ
๋ ์ดํ๋ถํฐ ์์ฑํ ์์์ ๋ง์ถฐ ์ฝ๋๊ฐ ํ๋์ฉ ๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ค
Execute the code block by order after hoisting.
โญ๏ธ hoisting์ด๋?
var,function declaration์ด ์ ์ผ ์๋ก ์ฌ๋ผ๊ฐ๋ ๊ฒ
โญ๏ธโญ๏ธํจ์์ ์ ์ธ์ ์ ์ผ ์๋ก!!!!โญ๏ธโญ๏ธ
ํธ์ด์คํ
์ด ๋ ์ดํ๋ถํฐ, ์ฝ๋๊ฐ ๋ํ๋๋ ๋๋ก, ์๋์ ์ผ๋ก ์คํ๋๋ค
asynchronous ๋น๋๊ธฐ์ ์ผ๋ก ์ธ์ ์ฝ๋๊ฐ ์คํ๋ ์ง ์์ธกํ ์ ์๋ ๊ฒ
console.log(1);
setTimeout(() => console.log(2), 1000);
console.log(3);
// JS์์ง์ ์ฝ๋๋ฅผ ์๋ถํฐ ์๋๋ก ์คํํ๋ค.
function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
// TimeHandler๋ผ๋ callbackํจ์์, timeout์ผ๋ก ์๊ฐ์ ์ง์ ํ๋ค
1-1. Synchronous callback
: ์ฆ๊ฐ์ , ๋๊ธฐ์ ์ผ๋ก ์คํ
function printImmediately(print) {
print();
}
// callbackํจ์๋ฅผ ๋ฐ์์ callback์ ๋ฐ๋ก ์คํํ๋ ํจ์๋ฅผ ๋ง๋ค์๋ค.
// callbackํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์, print๋ก callbackํจ์๋ฅผ ๋ฐ์ ์๋ฆฌ๋ฅผ ๋ง๋ค์ด๋๋๋ค.
printImmediately(() => console.log("hello"));
- โญ๏ธ JS์์ง์ด ์ด๋ป๊ฒ ์ดํดํ์๊น? hoisting!
1-2. Asynchronous callback
: ๋์ค์,์ธ์ ๋ ์ง ์ ์ ์๋ ๋น๋๊ธฐ์ ์ผ๋ก ์คํ
function printWithDelay(print, timeout) {
setTimeout(print, timeout);
}
printWithDelay(() => console.log("async callback"), 2000);
// ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ธฐ๋ฅ์ ๋์ํ๋ callback ํจ์๋ฅผ ์ ๋ฌํด์ผํจ
- โญ๏ธ JS์์ง์ด ์ด๋ป๊ฒ ์ดํดํ์๊น? hoisting!
callback hell example
class UserStorage {
loginUser(id, password, onSuccess, onError) {
// callbackํจ์๋ฅผ ๋ฃ๊ธฐ ์ํ ์๋ฆฌ๋ฅผ ๋ง๋ค์ด๋ .
// parameter๋ฅผ ๊ทธ๋ฅ ๋ฐ์ ์๋์๊ณ callbackํจ์๋ก ๋ฐ์ ์๋ ์๋ค
setTimeout(() => {
if (
(id === "ellie" && password === "dream") ||
(id === "coder" && password === "academy")
) {
onSuccess(id); ์ ๋ฌ๋ฐ์ onSuccess๋ฅผ ๋ถ๋ฅด๊ณ id๋ฅผ ์ ๋ฌํ๋ค
} else {
onError(new Error("not found"));
}
}, 2000);
}
//์ญํ ๋ฐ์์ฌ ๋
getRoles(user, onSuccess, onError) {
setTimeout(() => {
if (user === "ellie") {
onSuccess({ name: "ellie", role: "admin" });
์ ๋ฌ๋ฐ์ onSuccess๋ฅผ ๋ถ๋ฅด๊ณ name๊ณผ role์ ์ ๋ฌํ๋ค
} else {
onError(new Error("not access"));
}
}, 1000);
}
}
const userStorage = new UserStorage();
const id = prompt("enter your id");
const password = prompt("enter your password");
// ์ฌ์ฉ์์ id, password๋ฅผ ๋ฐ์์ค๊ณ
userStorage.loginUser(
id,
password,
(user) => {
userStorage.getRoles(
user,
(userWithRole) => {
alert(`Hello, ${user.name}, you have a ${user.role} role`);
// ๋ก๊ทธ์ธํ์ ๋ user๋ id๋ง ์์.
alert(
`Hello, ${userWithRole.name}, you have a ${userWithRole.role} role`
);
},
//์ด๊ฒ ์คํ๋๋ ค๋ฉด, loginUser ์ฑ๊ณต + getRoles ์ฑ๊ณต
(error) => {
onsole.log("error");
}
);
},
//์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์ฑ๊ณตํ๋ฉด, userStorage์์ getRole๋ก ์ญํ ์ ๋ฐ์์์ผํจ
(error) => console.log("error")
);
// ๋ก๊ทธ์ธ์ ํด์ผํจ. userStorage์ loginUser์ ๋ฐ์์จ id์ password๋ฅผ ์ ๋ฌ
์ฝ๋ฐฑ ํจ์ ์์์ ๋ค๋ฅธ๊ฒ์ ํธ์ถํ๊ณ , ๊ทธ ์์์ ๋๋ค๋ฅธ ์ฝ๋ฐฑ์ ์ ๋ฌํ๊ณ , ํธ์ถํ๊ณ ์ ๋ฌ์ ๋ฌโฆ.
=>์ฝ๋ฐฑ ์ง์ฅ!
์ด ์ฝ๋ฐฑ์ง์ฅ์ ์์!
- ๋ก๊ทธ์ธํ ๋ค์์(loginUser)
- ๊ทธ ๋ก๊ทธ์ธํ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด์(userStorage)
- ์ฌ์ฉ์์ ์ญํ ์ ๋ฐ์์ค๋๊ตฌ๋(getRoles)
๋ฌธ์ ์ !
- ๊ฐ๋ ์ฑ์ด ๋งค์ฐ ๋จ์ด์ง๊ณ , ์์๊ฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ์ดํดํ๋ ๊ฒ๋ ํ๋ค๋ค
- ์๋ฌ๋ฐ์์, ์ฒด์ธ์ด ๊ธธ์๋ก ๋๋ฒ๊น ์ด ํ๋ค๋ค
๋น๋๊ธฐ ํจ์๋ฅผ ์ฐ๋ ค๋ฉด callback์ง์ฅ์ ๋ง๋ค ์ ๋ฐ์ ์๋๋ฐ, ๊ทธ๋ผ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ์ฐ๋ ค๋ฉด ์ด๋ป๊ฒ ํด??
๋ค์ํธ,Promise์์!