** ๐ 4-1๋จ๊ณ: Ajax ์ํ ์ผ๊ด์ฑ ๋ฌธ์ ์ ์์ฒญ ์ทจ์ ์ฒ๋ฆฌ**
โ ์ฌ๋ฌ ๊ฐ์ Ajax ์์ฒญ์ด ๋์์ ์ฒ๋ฆฌ๋ ๋ ๋ฐ์ํ๋ ์์ ๊ผฌ์ ๋ฌธ์ ,
๐ ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฑธ ์ทจ์ํ๋ ๋ฐฉ๋ฒ๊น์ง ์๋ฒฝํ๊ฒ ๋ง์คํฐํ๋ ๋จ๊ณ์ ๋๋ค.
โ 1. ์ํ ์ผ๊ด์ฑ์ด ๋ญ์ผ?
โ ํ๋ฉด์ ๋ณด์ฌ์ง๋ ๋ด์ฉ์ด ์ค์ ์๋ฒ ์ํ์ ์ ํํ ์ผ์นํ๋ ๊ฒ
๐ฆ๐ป ์ฌ์ด ์
1. ๊ฒ์์ฐฝ์ "apple" ์
๋ ฅ โ Ajax ์์ฒญ 1 ๋ฐ์ฌ
2. ๋ฐ๋ก "banana" ์
๋ ฅ โ Ajax ์์ฒญ 2 ๋ฐ์ฌ
๐จ ๊ทธ๋ฐ๋ฐโฆ
- โappleโ ์๋ต์ด ๋ฆ๊ฒ ๋์ฐฉํ๊ณ
- โbananaโ ์๋ต์ด ๋จผ์ ๋์ฐฉํ๋ฉด?
๐ฅ ๊ฒ์์ฐฝ์๋ โbananaโ๋ผ๊ณ ์ผ๋๋ฐ,
๊ฒฐ๊ณผ๋ apple์ด ๋์๋ฒ๋ฆฌ๋ ๋ฌธ์ ๋ฐ์!
โ ์ด๊ฑธ ์๋ต ์์ ์ญ์ ๋ฌธ์ (Race Condition)๋ผ๊ณ ํด์.
โ 2. Race Condition (๋ ์ด์ค ์ปจ๋์ )
๐ฆ ์ ์
์ฌ๋ฌ ์์ฒญ์ด ๋์์ ์ฒ๋ฆฌ๋ ๋, ๋์ฐฉ ์์๊ฐ ๊ผฌ์ด๋ฉด์ ๊ฒฐ๊ณผ๊ฐ ์ํค๋ ํ์
๐ง ์ ๋ฐ์ํ๋์?
- ๋คํธ์ํฌ ์๋๋ ์ํฉ๋ง๋ค ๋ค๋ฆ (๋น ๋ฅผ ์๋, ๋๋ฆด ์๋ ์์)
- Ajax๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น๋๊ธฐ(์์๋ฅผ ๋ณด์ฅํ์ง ์์)
โ ์๋ชป๋ ์์ ์ฝ๋
input.addEventListener("input", e => {
fetch(`/search?q=${e.target.value}`)
.then(res => res.text())
.then(html => {
resultBox.innerHTML = html;
});
});
โ ๋น ๋ฅด๊ฒ ํ์ดํํ๋ฉด ์ค๋๋ ์๋ต์ด ๋์ค์ ๋์ฐฉํด ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฐ๋
โ 3. ํด๊ฒฐ ์ ๋ต โ : ์์ฒญ ์ทจ์ (AbortController)
๐ฆ AbortController๋?
JavaScript์์ ํ์ฌ ์งํ ์ค์ธ fetch ์์ฒญ์ ์ค๋จํ ์ ์๊ฒ ํด์ฃผ๋ API
โ ์์ ์ฝ๋
let controller;
function search(keyword) {
if (controller) controller.abort(); // ์ด์ ์์ฒญ ์ค๋จ
controller = new AbortController();
fetch(`/search?q=${keyword}`, { signal: controller.signal })
.then(res => res.text())
.then(data => {
resultBox.innerHTML = data;
})
.catch(err => {
if (err.name === "AbortError") {
console.log("์์ฒญ์ด ์ค๋จ๋์์ต๋๋ค.");
}
});
}
controller.abort()
โ ๊ธฐ์กด ์์ฒญ์ ์ค์งํจsignal
โ ์ด ์์ฒญ์ด ์ค์ง๋๋ฉด ์๋ฆผ์ ์ค.catch()
โ ์ค๋จ๋ ์์ฒญ์ ๊ฐ์งํ๊ณ ๋ฌด์ํจ
โ 4. ํด๊ฒฐ ์ ๋ต โก: ๊ฐ์ฅ ๋ง์ง๋ง ์์ฒญ๋ง ๋ฐ์
๐ฆ ์ ์ญ ์์ฒญ ID ๋ฐฉ์
let latestRequestId = 0;
function search(keyword) {
const currentId = ++latestRequestId;
fetch(`/search?q=${keyword}`)
.then(res => res.text())
.then(data => {
if (currentId === latestRequestId) {
resultBox.innerHTML = data; // ์ต์ ์์ฒญ๋ง ๋ฐ์
}
});
}
๐ ์ค๋๋ ์์ฒญ์ด ์๋ตํ๋๋ผ๋, ID๊ฐ ๋ค๋ฅด๋ฉด ๋ฌด์ํจ
โ โ ์ด ๋ฐฉ์์ โ์ทจ์โ๋ ์ ํ์ง๋ง โ๊ฒฐ๊ณผ๋ฅผ ๋ฌด์โํด์ ์์ ์ ์
โ 5. Axios CancelToken (Axios 0.x)
Axios์์๋ ๊ณผ๊ฑฐ์ CancelToken์ ์ฌ์ฉํด ์์ฒญ์ ์ค๋จํ์ด์ (ํ์ฌ๋ AbortController ๊ถ์ฅ)
์์ ์ฝ๋
let cancel;
axios.get('/search', {
cancelToken: new axios.CancelToken(function executor(c) {
cancel = c; // ์ทจ์ ํจ์ ๋ฑ๋ก
})
});
// ์ทจ์ํ๊ธฐ
if (cancel) cancel("์์ฒญ ์ทจ์๋จ");
๐ก ํ์ฌ๋ fetch์ AbortController
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ํ์ค์ด์์.
โ 6. ๋ฉด์ ์ง๋ฌธ ์์ + ํด์ค
โ Q. ๋น ๋ฅด๊ฒ ๋ฐ๋ณต๋๋ Ajax ์์ฒญ์์ ์๋ต์ด ๊ผฌ์ด๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ค๋ฉด ์ด๋ป๊ฒ ์ฒ๋ฆฌํ์๊ฒ ์ต๋๊น?
โ A.
- ์ด ํ์์ Race Condition์ผ๋ก, ๋น ๋ฅด๊ฒ ๋ฐ์ํ Ajax ์์ฒญ์ด ๋์ค์ ๋์ฐฉํ๋ ๊ฒฝ์ฐ ๋ฐ์
- ํด๊ฒฐ์ฑ
์ผ๋ก๋
AbortController
๋ฅผ ์ด์ฉํ์ฌ ์ด์ ์์ฒญ์ ์ทจ์ํ๊ฑฐ๋, - ์์ฒญ๋ง๋ค ๊ณ ์ ID๋ฅผ ๋ถ์ฌํ๊ณ ๊ฐ์ฅ ์ต๊ทผ ์์ฒญ๋ง ํ๋ฉด์ ๋ฐ์ํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํฉ๋๋ค
โ ์ ์ฒด ์์ฝ ์นด๋
๊ฐ๋ | ์ค๋ช |
---|---|
์ํ ์ผ๊ด์ฑ | ํ๋ฉด๊ณผ ์๋ฒ ์ํ๊ฐ ์ ํํ ์ผ์นํ๋ ๊ฒ |
Race Condition | ์ค๋๋ ์์ฒญ์ด ๋์ค์ ๋์ฐฉํด์ ๊ฒฐ๊ณผ๋ฅผ ๋ฎ์ด์ |
AbortController | ์งํ ์ค์ธ fetch ์์ฒญ์ ์ทจ์ํ ์ ์์ |
์์ฒญ ID ์ถ์ | ์ต์ ์์ฒญ๋ง ๋ฐ์ํ๊ณ ์ด์ ๊ฒฐ๊ณผ๋ ๋ฌด์ํจ |
Axios CancelToken | Axios ์์ฒญ์ ์ทจ์ํ๋ ๋ฐฉ์ (์ด์ ๋ฐฉ์) |
โ ์๋๋ฆฌ์ค ๋น๊ต ์ ๋ฆฌ
์ํฉ | ํด๊ฒฐ ์ ๋ต |
---|---|
๋น ๋ฅธ ์ ๋ ฅ ์ค Ajax ์ค๋ณต ๋ฐ์ | Debounce + AbortController |
์๋ต ์์๊ฐ ๊ผฌ์ฌ ํ๋ฉด์ด ์ํด | ์์ฒญ ID ๋น๊ต ๋๋ ์๋ต ๋ฌด์ |
์ค์๊ฐ ๊ฒ์/ํํฐ๋ง | ๋ง์ง๋ง ์์ฒญ๋ง ๋ฐ์ or ์ด์ ์์ฒญ ์ทจ์ |
โ 4-2๋จ๊ณ: ๋ณ๋ ฌ Ajax ์ฒ๋ฆฌ์ Promise ๋ณ๋ ฌ์ฑ ์์ ์ ๋ณต
โ๋์์ ์ฌ๋ฌ Ajax๋ฅผ ๋ณด๋ด์ ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋ ค๋ฉด?โ
โ Promise์ async/await๋ก ๋๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ด์!
โ 1. ์๋ฐ์คํฌ๋ฆฝํธ๋ โ๋จ์ผ ์ฐ๋ ๋โ ์ธ์ด์ ๋๋ค
๐ฆ ์ฝ๊ฒ ๋งํ๋ฉด:
์๋ฐ์คํฌ๋ฆฝํธ๋ ํ ๋ฒ์ ํ ์ค์ฉ๋ง ์คํํ ์ ์์ด์
(๐ ํ ์ค ์๋ฆฌ์ฌ๊ฐ ํ ๋ฒ์ ํ๋์ฉ๋ง ์๋ฆฌํ๋ ๋๋)
ํ์ง๋ง Ajax ๊ฐ์ ๋คํธ์ํฌ ์์ฒญ์ ๋น๋๊ธฐ๋๊น
โ์ผ๋จ ๋ณด๋ด๊ณ , ๋์ค์ ๊ฒฐ๊ณผ ์ค๋ฉด ์ฒ๋ฆฌโ๋ฅผ ํ ์ ์์ด์.
โ ์ด๊ฑธ ๋์์ฑ(Concurrency)์ด๋ผ๊ณ ํด์!
โ 2. ์ฌ๋ฌ Ajax๋ฅผ ๋์์ ๋ณด๋ด๊ณ ์ถ๋ค๋ฉด?
โ ์๋ชป๋ ๋ฐฉ๋ฒ: ์์ฐจ ์ฒ๋ฆฌ
const res1 = await fetch('/user');
const res2 = await fetch('/posts');
const res3 = await fetch('/comments');
์ด๊ฑด 1๊ฐ๊ฐ ๋๋์ผ ๋ค์ ์์ฒญ ์์
โ ์ด 3์ด ๊ฑธ๋ฆด ์ ์์ (๊ฐ 1์ด ์์๋ผ๊ณ ๊ฐ์ ์)
โ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ๋ณ๋ ฌ ์ฒ๋ฆฌ (Promise.all)
๐ฆ Promise.all์ด๋?
์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์ ์ ํ ๋ฒ์ ๋ณ๋ ฌ๋ก ์์ํด์,
โ ๋ชจ๋ ์๋ฃ๋๋ฉด ๊ฒฐ๊ณผ๋ฅผ ํ๊บผ๋ฒ์ ๋ฐ๋ ๋ฐฉ์
๐ฆ๐ป ์ฌ์ด ์ค๋ช
3๊ฐ์ ํ๋ฒ๊ฑฐ ์ฃผ๋ฌธ์ ํ ๋ช ์ฉ ๋ฐ๋ ๊ฒ ์๋๋ผ,
โ 3๊ฐ ๋์์ ๋ง๋ค์ด์ ํ ๋ฒ์ ๋ฐ๋ ๋๋!
โ ์์ ์ฝ๋
const [user, posts, comments] = await Promise.all([
fetch('/user').then(r => r.json()),
fetch('/posts').then(r => r.json()),
fetch('/comments').then(r => r.json())
]);
console.log(user, posts, comments);
- ๐ก 3๊ฐ ์์ฒญ์ด ๋์์ ์์๋จ
- ๐ฆ ๋ชจ๋ ์ฑ๊ณตํ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ฆฌํด
- โ ๋จ์ : ํ๋๋ผ๋ ์คํจํ๋ฉด ์ ์ฒด ์คํจ๋จ
โ 3. Promise.race
๐ฆ race๋?
์ฌ๋ฌ ์์ ์ค ๊ฐ์ฅ ๋จผ์ ๋๋๋ ๊ฒ ํ๋๋ง ๋ฐํํ๊ณ ๋๋จธ์ง๋ ๋ฌด์!
๐ฆ๐ป ์ฌ์ด ์ค๋ช
๋ฌ๋ฆฌ๊ธฐ ๊ฒฝ์ฃผ์ฒ๋ผ, ๊ฐ์ฅ ๋จผ์ ๋์ฐฉํ ๊ฒฐ๊ณผ๋ง ์ฌ์ฉํ๋ ๋ฐฉ์
โ ์์ ์ฝ๋
const fastest = await Promise.race([
fetch('/mirror1'),
fetch('/mirror2'),
fetch('/mirror3')
]);
๐ ์ฌ๋ฌ ์๋ฒ ์ค ๊ฐ์ฅ ๋น ๋ฅธ ์๋ฒ์ ์๋ต๋ง ์ฌ์ฉ
โ CDN, ๋ฐฑ์ ์๋ฒ, ์๋ ์ฐ์ ์ ๋ต์ ์ ์ฉ
โ 4. async/await์ ๋ณ๋ ฌ ์ฒ๋ฆฌ ํจ๊ป ์ฐ๊ธฐ
๐ฆ async/await๋?
Promise๋ฅผ ๋ ์ฝ๊ธฐ ์ฌ์ด ์ฝ๋๋ก ๋ฐ๊ฟ์ฃผ๋ ๋ฌธ๋ฒ
์์
async function getAll() {
const [a, b] = await Promise.all([
fetch('/a').then(res => res.json()),
fetch('/b').then(res => res.json())
]);
return a + b;
}
- ๊ฐ๋ ์ฑ ์ข์
- try/catch๋ก ์์ธ ์ฒ๋ฆฌ๋ ํธํจ
โ 5. ์ค๋ฌด์์์ ๋์์ฑ ์ ์ด
๊ธฐ์ | ์ค๋ช |
---|---|
Promise.all() |
๋ชจ๋ ์์ ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆผ |
Promise.race() |
๊ฐ์ฅ ๋น ๋ฅธ ๊ฒฐ๊ณผ๋ง ์ฌ์ฉ |
Promise.any() |
๊ฐ์ฅ ๋จผ์ ์ฑ๊ณตํ ๊ฒ๋ง ์ฌ์ฉ (์คํจ๋ ๋ฌด์) |
async/await |
๋น๋๊ธฐ ์ฝ๋๋ฅผ ์์ฐจ์ฒ๋ผ ์์ฑ ๊ฐ๋ฅ |
AbortController |
์ค๊ฐ์ ์์ฒญ์ ์ทจ์ํ ์ ์์ |
์์ฒญ ํ | ์์๋ฅผ ์ ํด์ ์์ฒญ์ ๊ด๋ฆฌ (์ค์ฒฉ ๋ฐฉ์ง) |
โ ๋ฉด์ ์ง๋ฌธ ์์ + ํด์ค
โ Q. ์ฌ๋ฌ Ajax๋ฅผ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๊ณ ์ถ์ต๋๋ค. ์ด๋ป๊ฒ ํ์๊ฒ ์ต๋๊น?
โ A.
Promise.all()
์ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ์์ฒญ์ ๋ณ๋ ฌ๋ก ์คํํ๊ณ- ์๋ต์ ๋ฐฐ์ด ํํ๋ก ๋ฐ์ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- ํน์ ์์ฒญ๋ง ๋จผ์ ๋ฐ๊ณ ์ถ๋ค๋ฉด
Promise.race()
๋๋Promise.any()
๋ฅผ ์ฌ์ฉํฉ๋๋ค. - ์ ์ฒด ๋ก์ง์
async/await
์ ์ฌ์ฉํ์ฌ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
โ ์ ์ฒด ์์ฝ ์นด๋
๊ธฐ์ | ์ค๋ช | ์ฌ์ฉ ์ํฉ |
---|---|---|
Promise.all | ๋ชจ๋ ์ฑ๊ณตํด์ผ ๊ฒฐ๊ณผ ๋ฐํ | ๋ณ๋ ฌ ๋ก๋ฉ |
Promise.race | ๊ฐ์ฅ ๋น ๋ฅธ ๊ฒฐ๊ณผ๋ง ์ฌ์ฉ | ์๋ฒ ์๋ ์ฐ์ |
async/await | Promise๋ฅผ ๊น๋ํ๊ฒ ํํ | ๋๋ถ๋ถ์ ์ค๋ฌด ์ฝ๋ |
์์ฒญ ํ | ์์๋๋ก Ajax ์ฒ๋ฆฌ | ์ค์ฒฉ ๋ฐฉ์ง, ์๋ ์กฐ์ |
AbortController | ์์ฒญ ์ทจ์ ๊ธฐ๋ฅ | ๋น ๋ฅธ ์ ๋ ฅ ์ทจ์, ์ค๋ณต ์ ๊ฑฐ |
โ ์๋๋ฆฌ์ค ๋น๊ต
์ํฉ | ์ฌ์ฉ ๊ธฐ์ |
---|---|
์ฌ์ฉ์ ์ ๋ณด + ๊ธ + ๋๊ธ โ ๋ชจ๋ ํ์ | Promise.all() |
์ฌ๋ฌ ์๋ฒ ์ค ๋น ๋ฅธ ๊ฒ๋ง ์ฌ์ฉ | Promise.race() |
๊ฒ์ ์ค ๋น ๋ฅด๊ฒ ์ด์ ์์ฒญ ์ทจ์ | AbortController |
์ฝ๋ ๊ฐ๋ ์ฑ ํฅ์ | async/await |
โ 4-3๋จ๊ณ: Ajax ์์ฒญ ํ ์ค๊ณ์ ๋ฐฑ์คํ ์ ๋ต ์์ ์ ๋ณต
๐ ์์ฒญ์ด ๋๋ฌด ๋ง์ ๋, ์๋ฒ๊ฐ ๋ฉ์ถ์ง ์๊ฒ ํ๊ณ ,
์์ฒญ์ ์์๋๋ก, ๋๋ํ๊ฒ, ํจ์จ์ ์ผ๋ก ๋ณด๋ด๋ ์ค๊ณ๋ฅผ ๋ฐฐ์๋๋ค.
โ 1. ์์ฒญ ํ(Request Queue)๋?
์ฌ๋ฌ ๊ฐ์ Ajax ์์ฒญ์ด ์์ ๋,
ํ ๋ฒ์ ๋ค ๋ณด๋ด์ง ์๊ณ ์ค์ ์ธ์์ ์์๋๋ก ํ๋์ฉ ์ฒ๋ฆฌํ๋ ๊ตฌ์กฐ
๐ฆ๐ป ์ฌ์ด ์ค๋ช
ํ๋ฒ๊ฑฐ ๊ฐ๊ฒ์์ ์๋์ด ๋ง์ ๋ ๋ฒํธํ๋ฅผ ๋ฝ๊ณ ์ค ์์ ์ฐจ๋ก๋๋ก ์ฃผ๋ฌธํ์ฃ ?
โ ๋ฐ๋ก ์ด๊ฒ ์์ฒญ ํ์ ๋๋ค!
๐ง ์ ํ์ํ๊ฐ์?
์ํฉ | ๋ฌธ์ |
---|---|
Ajax ์์ฒญ์ด ๋์์ 50๊ฐ ๋ฐ์ | ์๋ฒ ๊ณผ๋ถํ / ์๋ต ์ง์ฐ / UI ๋ฒ๋ฒ ๊ฑฐ๋ฆผ |
์ค๋ณต๋ ์์ฒญ์ด ๋ฐ๋ณต๋จ | ๋ญ๋น, ๊ผฌ์, ์ ํฉ์ฑ ์ค๋ฅ |
โ ๊ทธ๋์ ์ฐ๋ฆฌ๋ ์์ฒญ์ ์์๋๋ก, ์ฐ์ ์์๋ณ๋ก, ํ์ํ ๋๋ง ๋ณด๋ด๋ ์ค๊ณ๊ฐ ํ์ํฉ๋๋ค.
โ 2. ๊ธฐ๋ณธ ๊ตฌ์กฐ: ์์ ํ ๋ง๋ค๊ธฐ
๐ ๏ธ ์์ ๊ตฌ์กฐ (๊ธฐ๋ณธ ํ)
class AjaxQueue {
constructor() {
this.queue = [];
this.isRunning = false;
}
enqueue(task) {
this.queue.push(task);
this.runNext();
}
async runNext() {
if (this.isRunning || this.queue.length === 0) return;
this.isRunning = true;
const nextTask = this.queue.shift();
try {
await nextTask();
} catch (e) {
console.error("์์ฒญ ์คํจ:", e);
}
this.isRunning = false;
this.runNext(); // ๋ค์ ์์
์คํ
}
}
โ ์ฌ์ฉ ์
const queue = new AjaxQueue();
queue.enqueue(() => fetch("/user1"));
queue.enqueue(() => fetch("/user2"));
queue.enqueue(() => fetch("/user3"));
๐ ์์ฒญ์ ํ๋์ฉ ์ฐจ๋ก๋๋ก ์คํ๋จ
โ ์๋ฒ ๊ณผ๋ถํ ๋ฐฉ์ง
โ ์๋ต ์์ ๋ณด์ฅ
โ 3. ์ฐ์ ์์ ๊ธฐ๋ฐ ์์ฒญ ํ
๐ฆ ๊ฐ๋
๊ธํ ์์ฒญ์ ๋จผ์ ์ฒ๋ฆฌํ๊ณ , ๋ ๊ธํ ๊ฑด ๋์ค์ ์คํํ๊ธฐ
๐ ๏ธ ์ฝ๋ ์์
class PriorityQueue {
constructor() {
this.queue = [];
this.isRunning = false;
}
enqueue(task, priority = 0) {
this.queue.push({ task, priority });
this.queue.sort((a, b) => b.priority - a.priority); // ๋์ ์ฐ์ ์์ ๋จผ์
this.runNext();
}
async runNext() {
if (this.isRunning || this.queue.length === 0) return;
this.isRunning = true;
const { task } = this.queue.shift();
try {
await task();
} finally {
this.isRunning = false;
this.runNext();
}
}
}
๐ฆ๐ป ์ฌ์ด ์ค๋ช
โ์๊ธ ํ์ ๋จผ์ , ๊ฐ๊ธฐ ํ์๋ ๋์ค์โ
โ ์ฐ์ ์์์ ๋ฐ๋ผ ๋จผ์ ์ฒ๋ฆฌ
โ ์ค๋ฌด ์์
์์ฒญ | ์ฐ์ ์์ |
---|---|
๋ก๊ทธ์ธ ์์ฒญ | ๐ฅ 10 (๊ฐ์ฅ ์ฐ์ ) |
์๋ฆผ ์ฒดํฌ | ๐จ 5 |
์ถ์ฒ ๊ฒ์๋ฌผ ๋ถ๋ฌ์ค๊ธฐ | ๐ฉ 2 |
โ 4. ๋ฐฑ์คํ ์ ๋ต(Back-off)
๐ฆ ๋ฐฑ์คํ๋?
์์ฒญ์ด ์คํจํ๊ฑฐ๋ ์๋ฒ๊ฐ ๊ณผ๋ถํ ์ํ์ผ ๋,
์ ๊น ๊ธฐ๋ค๋ ธ๋ค๊ฐ ๋ค์ ์์ฒญํ๋ ์ ๋ต์ ๋๋ค.
๐ฆ๐ป ์ฌ์ด ์ค๋ช
๋ฌธ์ ๋๋๋ ธ๋๋ฐ ์ฌ๋์ด ์์ด์.
๐ 5์ด ํ ๋ค์ ๋๋๋ฆผ โ ๊ทธ๋๋ ์์ผ๋ฉด โ 10์ด ํ ๋ค์ โ โฆ
โ ์ ์ ๊ฐ๊ฒฉ์ ๋๋ฆฌ๋ฉฐ ๊ธฐ๋ค๋ฆฌ๋ ๊ฑฐ์์.
๐ ๋ํ ์ ๋ต: ์ง์ ๋ฐฑ์คํ (Exponential Back-off)
let attempt = 0;
function retryAjax() {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s, 8s...
setTimeout(() => {
fetch("/data")
.then(res => res.json())
.then(data => console.log(data))
.catch(() => {
attempt++;
retryAjax(); // ์คํจํ๋ฉด ๋ค์ ์๋
});
}, delay);
}
โ ์ค๋ฌด ์ ์ฉ ์์น
์ํฉ | ๋ฐฑ์คํ ์ ์ฉ |
---|---|
์๋ฒ๊ฐ 500 ์๋ฌ ์๋ต | โ ๋ฐฑ์คํ ํ ์ฌ์๋ |
๋คํธ์ํฌ ๋๊น | โ 3์ด, 6์ด, 12์ด ๊ฐ๊ฒฉ์ผ๋ก ์ฌ์๋ |
๋๋ฌด ๋ง์ ์์ฒญ | โ ์ผ์ ์๊ฐ ๋์ ์ค์ง ํ ์ฌ์๋ |
โ ๋ฉด์ ์ง๋ฌธ ์์ + ํด์ค
โ Q. ์ค์๊ฐ Ajax ์์ฒญ์ด ๋๋ฌด ๋ง์ ์๋ฒ๊ฐ ๋๋ ค์ง๋๋ค. ์ด๋ป๊ฒ ์ต์ ํํ์ค ๊ฑด๊ฐ์?
โ A.
- ์์ฒญ ํ ๊ตฌ์กฐ๋ฅผ ๋์ ํด ์์ฒญ์ ์์๋๋ก ์ฒ๋ฆฌํ๊ณ ,
- ์ฐ์ ์์ ํ๋ฅผ ํ์ฉํด ์ค์ํ ์์ฒญ๋ถํฐ ๋จผ์ ์คํํฉ๋๋ค.
- ํธ๋ํฝ์ด ๊ณผ๋ํ๊ฒ ๋ชฐ๋ฆด ๊ฒฝ์ฐ, ์ง์ ๋ฐฑ์คํ๋ฅผ ํตํด ์ผ์ ๊ฐ๊ฒฉ์ผ๋ก ์ฌ์์ฒญํ์ฌ ์๋ฒ๋ฅผ ๋ณดํธํฉ๋๋ค.
โ ์ ์ฒด ์์ฝ ์นด๋
๊ธฐ์ | ์ค๋ช | ํจ๊ณผ |
---|---|---|
์์ฒญ ํ | ์์ฒญ์ ์ค ์ธ์์ ์์ฐจ ์ฒ๋ฆฌ | ๊ณผ๋ถํ ๋ฐฉ์ง |
์ฐ์ ์์ ํ | ๊ธํ ์์ฒญ ๋จผ์ ์ฒ๋ฆฌ | UX ๊ฐ์ |
๋ฐฑ์คํ | ์คํจ ์ ์ ์ ์ฒ์ฒํ ์ฌ์๋ | ์๋ฒ ๋ณดํธ |
โ ์๋๋ฆฌ์ค ์ ๋ฆฌ
์ํฉ | ์ ์ฉ ๊ธฐ์ |
---|---|
๋ก๊ทธ์ธ ์์ฒญ โ ๊ผญ ๋จผ์ ์ฒ๋ฆฌ๋ผ์ผ ํจ | ์ฐ์ ์์ ํ |
10๊ฐ ์์ฒญ์ ์ฐ์ ๋ณด๋ | ์ผ๋ฐ ์์ฒญ ํ |
์๋ฒ๊ฐ ๋ฐ์ ๋ ์์ฒญ ์คํจ | ๋ฐฑ์คํ ์ ๋ต |