function aaa(qqq){
// ํจ์ ๋ก์ง
}
aaa(function(){})
์ฐ๋ฆฌ๋ ํจ์๋ ์ธ์๋ก ์ ๋ฌํ ์ ์๋ค. ์ฌ๊ธฐ์ ์ธ์๋ก ์ ๋ฌ๋๋ ํจ์๋ฅผ callback ํจ์๋ผ๊ณ ํ๋ค. ์ ์ฝ๋์์ function(){}
์ด callback ํจ์๋ค.
["์ฒ ์", "์ํฌ", "ํ์ด"]. map((el) => {})
map ๊ดํธ ์์๋ ํ์ดํ ํจ์ ํํ์ callback ํจ์๊ฐ ์กด์ฌํ๋ค!
๊ทธ๋ ๋ค๋ฉด ์ callback ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฑธ๊น?
async/await ๋์ค๊ธฐ ์ ์๋, api ์์ฒญ์ด ๋๋๋ฉด ๊ทธ ๊ฒฐ๊ณผ๊ฐ์ ๊ฐ์ง๊ณ ๋ค๋ฅธ ์์ฒญ์ ์คํ์ํค๊ธฐ ์ํด callback ํจ์
๋ฅผ ์ฐ๊ณค ํ๋ค.
function aaa(qqq){
// ์ธ๋ถ API์ ๋ฐ์ดํฐ ์์ฒญํ๋ ๋ก์ง
// ...
// ...
// ์์ฒญ ๋!
const result = "์์ฒญ์ผ๋ก ๋ฐ์์จ ๋ฐ์ดํฐ ๊ฒฐ๊ณผ๊ฐ"
qqq(result) // ์์ฒญ ๋๋๋ฉด qqq ์คํ์ํค๊ธฐ
}
aaa(result) => {
console.log("์์ฒญ์ด ๋๋ฌ์ต๋๋ค.")
console.log("์์ฒญ์ผ๋ก ๋ฐ์์จ ๋ฐ์ดํฐ๋" + result + "์
๋๋ค")
}
์ฐ๋ฆฌ๋ ์ด๋ฏธ async/await๋ฅผ ์ต์ํ๊ฒ ์ฐ๊ณ ์์ง๋ง, ๋ค์ํ ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ ์๊ณ ์ฌ์ฉํ๋ ๊ฒ๋ ์ค์ํ๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<title> ์ฝ๋ฐฑ๊ณผ ์น๊ตฌ๋ค </title>
<script>
const myCallback = ()=>{
// 1.๋๋คํ ์ซ์๋ฅผ ๊ฐ์ง๊ณ ์ค๋ API
// 2.posts/๋๋ค์ซ์
// 3.๋๋ค์ซ์ ๋ฒ ๊ฒ์๊ธ ์์ฑํ ์ ์ ๊ฐ ์ด ๋ค๋ฅธ ๊ธ
}
const myPromise = ()=>{
}
const myAsyncAwait = ()=>{
}
</script>
</head>
<body>
<button onclick={onClickCallback}>Callback ์์ฒญํ๊ธฐ</button>
<button onclick={onClickPromise}>Promise ์์ฒญํ๊ธฐ</button>
<button onclick={onClickAsyncAwait}>AsyncAwait ์์ฒญํ๊ธฐ</button>
</body>
</html>
์์ myCallback
ํจ์ ๋ด๋ถ์์๋ 1๋ฒ ๋ก์ง์ ์๋ฃํ ํ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก 2๋ฒ ๋ก์ง์ ๊ทธ๋ฆฌ๊ณ , 2๋ฒ ๋ก์ง ์๋ฃ ํ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก 3๋ฒ ๋ก์ง์ ์คํํ๋ค.
nyCallback ํจ์๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ด์ค ์ ์๋ค.
const myCallback = ()=>{
// newXMLHTTPRequest๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ด์ฅ๋์ด์๋ ๊ธฐ๋ฅ
const aa = newXMLHTTPRequest()
aa.open("get",`http://numbersapi.com/random?min=1&max=200`)
aa.send()
aa.addEventListener("load",function(res){
console.log(res)
})
}
XMLHttpRequest
๋ ์๋ฒ์ ์ํธ ์์ฉํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ฐ์ฒด๋ค. ์ ์ฒด ํ์ด์ง์ ์๋ก๊ณ ์นจ ์์ด๋ URL๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ์ ์๋ค. Ajax ํ๋ก๊ทธ๋๋ฐ์ ์ฃผ๋ก ์ฌ์ฉ๋๊ณ , XHR์ด๋ผ๊ณ ์ค์ฌ ๋ถ๋ฅด๊ธฐ๋ ํ๋ค.
์ฒซ ๋ฒ์งธ์ response(res)
๋ฅผ ๊ฐ๊ณตํด์ ๋ ๋ฒ์งธ API ์์ฒญ์ ๋ณด๋ด๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ๋๋ค.
const myCallback = () => {
const aa = new XMLHttpRequest();
aa.open("get", "http://numbersapi.com/random?min=1&max=200");
aa.send();
aa.addEventListener("load", (res: any) => {
const num = res.target.response.split(" ")[0]; // ๋๋ค ์ ์ถ์ถ
// ๋๋ฒ์งธ api ์์ฒญ
const bb = new XMLHttpRequest();
bb.open("get", `https://koreanjson.com/posts/${num}`);
// num์ ์ถ์ถํ ๋๋ค ์๊ฐ ๋ค์ด๊ฐ
bb.send();
bb.addEventListener("load", (res: any) => {
console.log(res)
const userId = JSON.parse(res.target.response).UserId
});
});
};
console์ ํตํด ๋๋ค ์์ ํด๋นํ๋ ๊ฒ์๊ธ ๋ฐ์ดํฐ๊ฐ res
์ ๋ค์ด์จ ๊ฒ์ ํ์ธํ ์ ์๋ค. ํ์ง๋ง ์๋ต๋ฐ์ ๋ฐ์ดํฐ๋ ๋ฌธ์์ด๋ก ๋์ด์์ด์ ๊ฐ๊ณต ๋ฐ ํ์ฉ์ด ์ด๋ ต๋ค.
JSON.parse()
๋ฅผ ์ด์ฉํด์ ๋ฌธ์์ด์ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ์ฃผ๊ณ , ํด๋น ๋ฐ์ดํฐ์ ์์ฑ์ ์ ๋ณด(UserId
)๋ฅผ ์ด์ฉํด์ ์ธ ๋ฒ์งธ ์์ฒญ์ ๋ณด๋ด์ค๋ค.
const onClickCallback = () => {
// ์ฒซ๋ฒ์งธ ๋๋ค์ซ์ api ์์ฒญ
const aaa = new XMLHttpRequest();
aa.open("get", "http://numbersapi.com/random?min=1&max=200");
aa.send();
aa.addEventListener("load", (res: any) => {
const num = res.target.response.split(" ")[0];
// ๋๋ฒ์งธ posts api ์์ฒญ
const bbb = new XMLHttpRequest();
bb.open("get", `https://koreanjson.com/posts/${num}`);
bb.send();
bb.addEventListener("load", (res: any) => {
const userId = JSON.parse(res.target.response).UserId;
// ์ธ๋ฒ์งธ UserId api ์์ฒญ
const ccc = new XMLHttpRequest();
cc.open("get", `https://koreanjson.com/posts?userId=${userId}`);
cc.send();
cc.addEventListener("load", (res: any) => {
console.log(res)
console.log("์ต์ข
๊ฒฐ๊ณผ๊ฐ !");
console.log(JSON.parse(res.target.response));
});
});
});
};
๋ ๋ฒ์งธ ์์ฒญ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก JSON.parse()
๋ฅผ ์ด์ฉํด์ ๋ฌธ์์ด์ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ์ค๋ค.
์์ฒญ์ด ๋ฐ๋ณต๋ ์๋ก ์ค๋ฅธ์ชฝ ๋ฐฉํฅ ๋๊ฐ์ ์ผ๋ก ์ฅ ํ์ด๋ ํํ๋ฅผ ๋ณผ ์ ์๋ค. API ์์ฒญ์ด ๊ฑฐ๋ญ๋๋ค๋ฉด ์ฝ๋์ ๊ฐ๋
์ฑ์ด ์ฌํ๊ฒ ๋จ์ด์ง ๊ฒ์ด๋ค. ์ด๋ฌํ ํ์์ ์ฝ๋ฐฑ์ง์ฅ
์ด๋ผ๊ณ ํ๋ค.
์ฝ๋ฐฑ์ง์ฅ์ ๋ง๊ณ ์ ๋์จ ๊ฒ์ด Promise
๋ค. ์์ callback์์ ํ๋ ์์
์ Promise ๊ฐ์ฒด์๋ ์ ์ฉํด๋ณด์๋ค.
Promise
๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ, ๊ทธ ์ค์์๋ ํนํ ์ธ๋ถ์์ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๋ ์์
์ ์ฌ์ฉ๋๋ค. promise ๊ฐ์ฒด๋ฅผ ์ด์ฉํด์ ๋ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ axios
์ด๊ธฐ ๋๋ฌธ์, axios๋ฅผ ์ค์ต์ ์ฌ์ฉํ๋ค.
๋ง์ฝ axios๋ฅผ ์ฌ์ฉํ์ง ์๊ณ Promise ๊ฐ์ฒด๋ฅผ ์ง์ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ๋๋ค.
const result = await new Promise((resolve, reject) => {
const aaa = new XMLHttpRequest();
aaa.open("get", "http://numbersapi.com/random?min=1&max=200");
aaa.send();
aaa.addEventListener("load", (res: any) => {
resolve(res)
});
})
// resolve : ์์ฒญ์ด ์ฑ๊ณตํ์ ๊ฒฝ์ฐ
// reject : ์์ฒญ์ด ์คํจํ์ ๊ฒฝ์ฐ
async/await๊ฐ ๋ฑ์ฅํ๊ธฐ ์ ์๋ promise ๊ฐ์ฒด์ ์ ๊ณต๋๋ .then
์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค. ๋ค์๊ณผ ๊ฐ์ด ์จ์ค ์ ์๋ค.
const onClickPromise = () => {
axios
.get("http://numbersapi.com/random?min=1&max=200")
.then((res) => {
const num = res.data.split(" ")[0];
return axios.get(`https://koreanjson.com/posts/${num}`);
})
.then((res) => {
const userId = res.data.UserId;
// prettier-ignore
return axios.get(`https://koreanjson.com/posts?userId=${userId}`)
})
.then((res) => {
console.log(res.data);
});
};
callback์ ๋นํด ํจ์ฌ ์ฝ๋๊ฐ ๊ฐ๋จํด์ก๋ค. promise๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ๊ฐ ์์ฒญ๋ค์ด ์ฒด์ธ์ผ๋ก ์ฐ๊ฒฐ๋๋๋ฐ, ์ด๊ฒ์ Promise Chain
๋๋ Promise Chaining
์ด๋ผ๊ณ ํ๋ค.
ํ์ง๋ง, promise๋ ์ง๊ด์ ์ด์ง ๋ชปํ๋ค. ๋ค์๊ณผ ๊ฐ์ด ํธ์ถ์ ๋ํ ๊ฒฐ๊ณผ๊ฐ์ ์์์ ๋ด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค.
const result = axios.get // === ์๋ต ====
ํจ์๋ฅผ ์คํํ๋ฉด ๊ฒฐ๊ณผ ๊ฐ์ด ์์ ํ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ Promise์ ํํ๋ก ๋ค์ด์จ๋ค.
๋ํ, Promise๋ ์ฝ๋์ ์คํ ์์๊ฐ ์ง๊ด์ ์ด์ง ๋ชปํ๋ค. axios
๋ฅผ ์ด์ฉํ ๋น๋๊ธฐ ์์
์ด TaskQueue ์์ ๋ค์ด๊ฐ, ์คํ ์์๊ฐ ๋ค๋ก ๋ฐ๋ฆฌ๊ฒ ๋๋ค.
async/await
๋ฅผ ์ด์ฉํ๋ฉด ์ฝ๋๊ฐ ์ง๊ด์ ์ด๊ณ ์ฌํํด์ง๋ค!
const onClickAsyncAwait = async () => {
// prettier-ignore
const res1 = await axios.get("http://numbersapi.com/random?min=1&max=200");
const num = res1.data.split(" ")[0];
const res2 = await axios.get(`https://koreanjson.com/posts/${num}`);
const userId = res2.data.UserId;
// prettier-ignore
const res3 = await axios.get(`https://koreanjson.com/posts?userId=${userId}`)
console.log(res3.data);
};
Promise ์ค์ต์ ํ๋ฉด์, Promise๋ก ์คํํ๋ ํจ์๋ ํ์คํฌ ํ์ ๋ค์ด๊ฐ๋ค๋ ๊ฒ์ ๋ ์ฌ๋ ค๋ณด์. ํ์คํฌ ํ๋ ๋ฑ ํ๋๋ง ์๋ ๊ฒ์ด ์๋๋ผ, ์ฌ๋ฌ ๊ฐ๊ฐ ๋์์ ์กด์ฌํ๋ค. ๊ทธ ์ค ๋ํ์ ์ธ ๋ ๊ฐ์ง ํ์คํฌ ํ๋ฅผ ๊ณต๋ถํ๋ค.
๋งคํฌ๋ก ํ์คํฌ ํ (MacroTaskQueue)
: setTimeout, setInterval ๋ฑ์ด ๋ค์ด๊ฐ๋ ํ
๋ง์ดํฌ๋ก ํ์คํฌ ํ (MicroTaskQueue)
: Promise ๋ฑ์ด ๋ค์ด๊ฐ๋ ํ
๋งคํฌ๋ก ํ์คํฌ ํ์ ๋ง์ดํฌ๋ก ํ์คํฌ ํ๊ฐ ๋ถ๋ชํ ๊ฒฝ์ฐ์๋ ๋ง์ดํฌ๋ก ํ์คํฌ ํ
๊ฐ ์ฐ์ ํ๋ค.
์ค์๋ก mutation api ์์ฒญ์ ์ฌ๋ฌ ๋ฒ ๋ณด๋ด๊ฒ ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด์ isSubmitting
์ ํ์ฉํด ๋ ๋ฒ์งธ ์์ฒญ๋ถํฐ๋ ๋ง์์ค ์ ์๋ค.
import axoios from 'axios'
export default function IsSubmitting(){
const [isSubmitting,setIsSubmitting] = useState(false)
const onClickSubmit = async ()=>{
// ๋ฑ๋กํ๋ ๋์์ ๋ฑ๋ก๋ฒํผ์ด ์๋ํ์ง ์๋๋ก ํจ
setIsSubmitting(true)
const result = await axios.get("https://koreanjson.com/posts/1")
// ๋ฑ๋ก์ด ์๋ฃ๋์๋ค๋ฉด ๋ค์ ๋ฒํผ์ด ๋์ํ๋๋ก ํจ
setIsSubmitting(false)
}
return(
<button onClick={onClickSubmit} disabled={isSubmitting}> ๋ฑ๋กํ๊ธฐ ๋ฑ์ API ์์ฒญ๋ฒํผ </button>
)
}
๊ทธ๋ฐ๋ฐ ์ฌ๊ธฐ์ setState๋ ์ต์ข ์ ์ผ๋ก ๋ฐ๋ ๊ฒฐ๊ณผ๊ฐ์ผ๋ก ๋ฐ์๋๋ค๊ณ ์๊ณ ์๋ค. ์์ ์ฝ๋์ฒ๋ผ setState๋ฅผ ์ฌ๋ฌ ๋ฒ ๋ฐ๊ฟ๋ ๋งจ ๋ง์ง๋ง ๊ฐ๋ง ๋ฐ์๋์ง ์๋?
์ด ๋ถ๋ถ์ await์ ๋ง์ดํฌ๋ก ํ์ ๊ด๊ณ๋ฅผ ์๊ณ ์์ด์ผ ํ๋ค.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>์ด๋ฒคํธ๋ฃจํ</title>
<script>
function onClickLoop() {
console.log("=======์์!!!!=======");
function aaa() {
console.log("aaa-์์");
bbb();
console.log("aaa-๋");
}
async function bbb() {
console.log("bbb-์์");
const friend = await "์ฒ ์";
console.log(friend);
}
aaa();
console.log("=======๋!!!!=======");
}
</script>
</head>
<body>
<button onclick="onClickLoop()">์์ํ๊ธฐ</button>
</body>
</html>
์ฝ์์ฐฝ์ ์ด์ด์ ํ์ธํด๋ณด๋ฉด ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ด ๋์จ๋ค.
๊ตฌ์ฒด์ ์ธ ํจ์ ์คํ ๊ณผ์
1. callstack์ onClickLoop ๋ค์ด์ด
2.====์์!!!!====
์ฝ์์ ์ฐํ
3. aaa ํจ์๊ฐ callstack์ ์์
4.aaa-์์
์ฝ์์ ์ฐํ
5. bbb ํจ์๊ฐ callstack์ ์์
6.bbb-์์
์ด ์ฝ์์ ์ฐํ
7. await์์ bbb ํจ์ ์ ์คํ ์ค๋จํ๊ณ , async ํจ์๊ฐ ๋ง์ดํฌ๋ก ํ์ ๋ค์ด๊ฐ(๋๊ธฐ)
8. bbb ํจ์ callstack์์ ์์ด์ง
9.aaa-๋
์ฝ์์ ์ฐํ. aaa ํจ์ callstack์์ ์์ด์ง
10.====๋!!!!====
์ฝ์์ ์ฐํ. onClickLoop ํจ์ callstack์์ ์์ด์ง
11. bbb await callstack์ ๊ฐ์ ธ์์ ์คํ.์ฒ ์
์ฝ์์ ์ฐํ
์๋ฐ์คํฌ๋ฆฝํธ๋ await
๊ฐ ๋์ค๋ฉด async๋ฅผ ๊ฐ์ธ๊ณ ์๋ ํจ์๊ฐ ํ๋ ์ผ์ ์ค๋จํ๊ณ ๋ง์ดํฌ๋ก ํ
์ ๋ค์ด๊ฐ๋ค!
๊ทธ๋ฆฌ๊ณ async๊ฐ ๊ฐ์ธ๊ณ ์๋ ํจ์๊ฐ ๋ง์ดํฌ๋ก ํ์ ๋ค์ด๊ฐ ๋์๋ ์คํํ๋ ์์น๋ฅผ ๊ธฐ์ตํ๋ค.
๋ฐ๋ผ์ ๋ง์ดํฌ๋ก ํ์์ ๋์ ์คํ๋ ๋์๋ ๊ธฐ์ตํ ์์น๋ถํฐ ์คํ๋๋ค.
๋ ๋ค๋ฅธ ๋ฌธ์ ๋ฅผ ํ์ด๋ณด์.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>์ด๋ฒคํธ๋ฃจํ</title>
<script>
function onClickLoop() {
console.log("=======์์!!!!=======");
function aaa() {
console.log("aaa-์์");
bbb();
console.log("aaa-๋");
}
async function bbb() {
console.log("bbb-์์");
await ccc();
console.log("bbb-๋");
}
async function ccc() {
console.log("ccc-์์");
const friend = await "์ฒ ์";
console.log(friend);
}
aaa();
console.log("=======๋!!!!=======");
}
</script>
</head>
<body>
<button onclick="onClickLoop()">์์ํ๊ธฐ</button>
</body>
</html>
์ฝ์์ ์ฐํ๋ ์์
=======์์!!!!=======
aaa-์์
bbb-์์
ccc-์์
aaa-๋
=======๋!!!!=======
์ฒ ์
bbb-๋
๊ตฌ์ฒด์ ์ธ ์คํ ๊ณผ์
1. onClickLoop callstack์ ์์
2.=======์์!!!!=======
์ฝ์์ ์ฐํ
3. aaa ํจ์ callstack์ ์์
4.aaa-์์
์ฝ์์ ์ฐํ
5. bbb ํจ์ ์คํ(callstack),bbb-์์
์ฝ์์ ์ฐํ
6. ccc ํจ์ ์คํ(callstack),ccc-์์
์ฝ์์ ์ฐํ
7. ccc ํจ์ ์ ํ๋๊ฑฐ ์ค๋จํ๊ณ , await ๋ถ๋ถ์ด ๋ง์ดํฌ๋กํ์ ๋ค์ด๊ฐ
8. bbb ํจ์ ์ await ๋ถ๋ถ๋ ๋ง์ดํฌ๋กํ์ ๋ค์ด๊ฐ
9.aaa-๋
์ฝ์์ ์ฐํ
10.=======๋!!!!=======
์ฐํ. onClickLoop ์ข ๋ฃ
11. ccc ํจ์(await ๋ถ๋ถ) callstack์ ๊ฐ์ ธ์ด
12.์ฒ ์
์ฐํ. ccc ํจ์ ์ข ๋ฃ
13. bbb ํจ์(await ๋ถ๋ถ) callstack์ผ๋ก ๊ฐ์ ธ์ด
14.bbb-๋
์ฐํ. bbb ํจ์ ์ข ๋ฃ