ํฐ์คํ ๋ฆฌ ๋ทฐ
[JavaScript] ํ๋ก๋ฏธ์ค(Promise)
๊ฐ๋ฐ๊ฐ๊ตด๐ธ 2022. 8. 17. 18:27์๋ฐ์คํฌ๋ฆฝํธ๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ํ๋์ ํจํด์ผ๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํ์ง๋ง ์ ํต์ ์ธ ์ฝ๋ฐฑ ํจํด์ ์ฝ๋ฐฑ ์ง์ฅ(Callback Hell)๋ก ์ธํด ๊ฐ๋ ์ฑ์ด ๋์๊ณ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ค ๋ฐ์ํ ์๋ฌ์ ์ฒ๋ฆฌ๊ฐ ๊ณค๋ํ๋ฉฐ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ฒ์ ์ฒ๋ฆฌํ๋ ๋ฐ๋ ํ๊ณ๊ฐ ์์์ต๋๋ค.
ES6์์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ ๋ค๋ฅธ ํจํด์ผ๋ก ํ๋ก๋ฏธ์ค(Promise)๋ฅผ ๋์ ํ์ผ๋ฉฐ ์ด๋ ์ ํต์ ์ธ ์ฝ๋ฐฑ ํจํด์ด ๊ฐ์ง ๋จ์ ์ ๋ณด์ํ๋ฉฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์์ ์ ๋ช ํํ๊ฒ ํํํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด์ ๋จ์
์ฝ๋ฐฑ ์ง์ฅ(Callbak Hell)
๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํ๋ฉด ํจ์ ๋ด๋ถ์ ๋น๋๊ธฐ๋ก ๋์ํ๋ ์ฝ๋๊ฐ ์๋ฃ๋์ง ์์๋ค ํด๋ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃ๋ฉ๋๋ค.
- ๋น๋๊ธฐ ํจ์๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ถ์ ๋ฐํํ ์ ์์
- ์์ ์ค์ฝํ์ ๋ณ์์ ํ ๋นํ ์๋ ์์
์๋ฅผ ๋ค์ด get ํจ์ ๋ด๋ถ์ onload ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋น๋๊ธฐ๋ก ๋์ํฉ๋๋ค.
let todos;
// GET ์์ฒญ์ ์ํ ๋น๋๊ธฐ ํจ์
const get = url => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
// โ ์๋ฒ์ ์๋ต์ ์์ ์ค์ฝํ์ ๋ณ์์ ํ ๋นํ๋ค.
todos = JSON.parse(xhr.response);
} else {
console.error(`${xhr.status} ${xhr.statusText}`);
}
};
};
// id๊ฐ 1์ธ post๋ฅผ ์ทจ๋
get('https://jsonplaceholder.typicode.com/posts/1');
console.log(todos); // โก undefined
- onload ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ get ํจ์๊ฐ ํธ์ถํ์ง ์๊ธฐ ๋๋ฌธ์ ์บ์นํ์ฌ ๋ฐํํ ์ ์์
- onload ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ๋ฐ์ธ๋ฉํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ์ธ์ ๋ console.log(todos)๊ฐ ์ข ๋ฃํ ์ดํ์ ํธ์ถ๋จ
๋ฐ๋ผ์ ๋น๋๊ธฐ ํจ์์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ(์๋ฒ์ ์๋ต ๋ฑ)์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ ๋น๋๊ธฐ ํจ์ ๋ด๋ถ์์ ์ํํด์ผ ํฉ๋๋ค. ์ด๋ ๋น๋๊ธฐ ํจ์๋ฅผ ๋ฒ์ฉ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋น๋๊ธฐ ํจ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค.
ํ์์ ๋ฐ๋ผ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ๋ฉด ํธ์ถ๋ ์ฝ๋ฐฑ ํจ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ๋ฉด ํธ์ถ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
// GET ์์ฒญ์ ์ํ ๋น๋๊ธฐ ํจ์
const get = (url, successCallback, failureCallback) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
// ์๋ฒ์ ์๋ต์ ์ฝ๋ฐฑ ํจ์์ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ํธ์ถํ์ฌ ์๋ต์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
successCallback(JSON.parse(xhr.response));
} else {
// ์๋ฌ ์ ๋ณด๋ฅผ ์ฝ๋ฐฑ ํจ์์ ์ธ์๋ก ์ ๋ฌํ๋ฉด์ ํธ์ถํ์ฌ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
failureCallback(xhr.status);
}
};
};
// id๊ฐ 1์ธ post๋ฅผ ์ทจ๋
// ์๋ฒ์ ์๋ต์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋น๋๊ธฐ ํจ์์ธ get์ ์ ๋ฌํด์ผ ํ๋ค.
get('https://jsonplaceholder.typicode.com/posts/1', console.log, console.error);
/*
{
"userId": 1,
"id": 1,
"title": "sunt aut facere ...",
"body": "quia et suscipit ..."
}
*/
ํ์ง๋ง ์ด๋ฌํ ์ฝ๋ฐฑ ํจ์๋ ์ฝ๋ฐฑ ์ง์ฅ์ ๋น ์ง ์ ์์ต๋๋ค. ์ฝ๋ฐฑ ์ง์ฅ์ด๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํตํด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ํ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ๋น๋๊ธฐ ํจ์๊ฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๊ณ ๋๋ค์ ๋น๋๊ธฐ ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ค๋ฉด ์ฝ๋ฐฑ ํจ์ ํธ์ถ์ด ์ค์ฒฉ๋์ด ๋ณต์ก๋๊ฐ ๋์์ง๋ ํ์์ด ๋ฐ์ํ๋ ๊ฒ์ ๋๋ค.
get('/step1', a => {
get(`/step2/${a}`, b => {
get(`/step3/${b}`, c => {
get(`/step4/${c}`, d => {
console.log(d);
});
});
});
});
์๋ฌ ์ฒ๋ฆฌ์ ํ๊ณ
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด์ ๋ฌธ์ ์ ์ค์์ ๊ฐ์ฅ ์ฌ๊ฐํ ๊ฒ์ ์๋ฌ ์ฒ๋ฆฌ๊ฐ ๊ณค๋ํ๋ค๋ ๊ฒ์ ๋๋ค. ์๋ฌ๋ ํธ์ถ์ ๋ฐฉํฅ(์ฝ ์คํ์ ์๋ ๋ฐฉํฅ)์ผ๋ก ์ ํ๋๊ธฐ ๋๋ฌธ์ ์๋์ ์์ ๊ฐ์ ์ํฉ์ด ๋ฐ์ํฉ๋๋ค.
try {
setTimeout(() => { throw new Error('Error!'); }, 1000);
} catch (e) {
// ์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ๋ค
console.error('์บ์นํ ์๋ฌ', e);
}
- ๋น๋๊ธฐ ํจ์์ธ setTimeout์ด ํธ์ถ๋๋ฉด setTimeout ํจ์์ ์คํ ์ปจํ ์คํธ๊ฐ ์์ฑ๋์ด ์ฝ ์คํ์ ํธ์๋์ด ์คํ๋จ
- setTimeout์ ๋น๋๊ธฐ ํจ์์ด๋ฏ๋ก ์ฝ๋ฐฑ ํจ์๊ฐ ํธ์ถ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃ๋์ด ์ฝ ์คํ์์ ์ ๊ฑฐ๋จ
- ์ดํ ํ์ด๋จธ๊ฐ ๋ง๋ฃ๋๋ฉด setTimeout ํจ์์ ์ฝ๋ฐฑํจ์๋ ํ์คํฌ ํ๋ก ํธ์๋๊ณ ์ฝ ์คํ์ด ๋น๋ฉด ํธ์๋์ด ์คํ๋จ
- ์ด๋, ์คํ๋๋ ์ฝ๋ฐฑ ํจ์์ ํธ์ถ์๋ setTimeout์ด ์๋๋ฏ๋ก ์๋ฌ๋ catch ๋ธ๋ก์์ ์บ์น๋์ง ์์
๋ฐ๋ผ์ ์ฝ๋ฐฑ ์ง์ฅ์ด๋ ์๋ฌ ์ฒ๋ฆฌ์ ๋ฌธ์ ๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํด ES6์์ ํ๋ก๋ฏธ์ค๊ฐ ๋์ ๋์์ต๋๋ค.
ํ๋ก๋ฏธ์ค์ ์์ฑ
Promise ์์ฑ์ ํจ์๋ฅผ new ์ฐ์ฐ์์ ํจ๊ป ํธ์ถํ๋ฉด Promise ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. (Promise๋ ํ์ค ๋นํธ์ธ ๊ฐ์ฒด)
Promise ์์ฑ์ ํจ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํํ ์ฝ๋ฐฑ ํจ์(executor ํจ์)๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ฐ ์ด ์ฝ๋ฐฑ ํจ์๋ resolve์ reject ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ผ๋ฉฐ ๋ด๋ถ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํํฉ๋๋ค.
- resolve : ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ๋ฉด ์ฝ๋ฐฑ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ resolve ํจ์๋ฅผ ํธ์ถ
- reject : ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ๋ฉด reject ํจ์๋ฅผ ํธ์ถ
// GET ์์ฒญ์ ์ํ ๋น๋๊ธฐ ํจ์
const promiseGet = url => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
// ์ฑ๊ณต์ ์ผ๋ก ์๋ต์ ์ ๋ฌ๋ฐ์ผ๋ฉด resolve ํจ์๋ฅผ ํธ์ถํ๋ค.
resolve(JSON.parse(xhr.response));
} else {
// ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด reject ํจ์๋ฅผ ํธ์ถํ๋ค.
reject(new Error(xhr.status));
}
};
});
};
// promiseGet ํจ์๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
promiseGet('https://jsonplaceholder.typicode.com/posts/1');
ํ๋ก๋ฏธ์ค๋ ๋ค์๊ณผ ๊ฐ์ด ํ์ฌ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ์งํ๋๊ณ ์๋์ง๋ฅผ ๋ํ๋ด๋ ์ํ(state)์ ๋ณด๋ฅผ ๊ฐ์ง๋๋ค.
ํ๋ก๋ฏธ์ค ์ํ ์ ๋ณด | ์๋ฏธ | ์ํ ๋ณ๊ฒฝ ์กฐ๊ฑด |
pending | ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์์ง ์ํ๋์ง ์์ ์ํ | ํ๋ก๋ฏธ์ค๊ฐ ์์ฑ๋ ์งํ ๊ธฐ๋ณธ ์ํ |
fulfilled | ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ(์ฑ๊ณต) | resolve ํจ์ ํธ์ถ |
rejected | ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ(์คํจ) | reject ํจ์ ํธ์ถ |
์์ฑ๋ ์งํ์ ํ๋ก๋ฏธ์ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก pending ์ํ์ ๋๋ค. ์ดํ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋๋ฉด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ resolve ํจ์๋ฅผ ํธ์ถํด fulfilled ์ํ๋ก ๋ณ๊ฒฝ / reject ํจ์๋ฅผ ํธ์ถํด rejected ์ํ๋ก ๋ณ๊ฒฝ๋๋ฉฐ ์ด๋ฅผ settled ์ํ๋ผ๊ณ ํฉ๋๋ค.
์ด๋ฌํ settled ์ํ๋ fulfilled / rejected ์๊ด์์ด pending์ด ์๋ ์ํ๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ํ๋ ์ํ๋ฅผ ๋งํ๋ฉฐ ์ผ๋จ settled ์ํ๊ฐ ๋๋ฉด ๋๋ ๋ค๋ฅธ ์ํ๋ก ๋ณํํ ์ ์์ต๋๋ค.
์ ๊ทธ๋ฆผ์ฒ๋ผ ํ๋ก๋ฏธ์ค๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ์ ๋๋ถ์ด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ(result)๋ ์ํ๋ก ๊ฐ์ง๋๋ค.
์ด์ฒ๋ผ ํ๋ก๋ฏธ์ค๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด์ ๋๋ค.
- ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ๋ฉด ํ๋ก๋ฏธ์ค๋ pending ์ํ์์ fulfilled ์ํ๋ก ๋ณํํ๋ฉฐ ๊ฒฐ๊ณผ๊ฐ 1์ ๊ฐ์ง
- ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ๋ฉด ํ๋ก๋ฏธ์ค๋ pending ์ํ์์ rejected ์ํ๋ก ๋ณํํ๋ฉฐ ๊ฒฐ๊ณผ๊ฐ Error ๊ฐ์ฒด๋ฅผ ๊ฐ์ง
ํ๋ก๋ฏธ์ค์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋
ํ๋ก๋ฏธ์ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ๊ฐ ๋ณํํ๋ฉด ์ด์ ๋ฐ๋ฅธ ํ์ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ์ํด ํ๋ก๋ฏธ์ค๋ ํ์ ๋ฉ์๋ then, catch, finally๋ฅผ ์ ๊ณตํฉ๋๋ค. ํ๋ก๋ฏธ์ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ๊ฐ ๋ณํํ๋ฉด ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์ ์ธ์๋ก ์ ๋ฌํ ์ฝ๋ฐฑ ํจ์๊ฐ ์ ํ์ ์ผ๋ก ํธ์ถ๋๋ฉฐ, ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์์ ํ๋ก๋ฏธ์ค์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ์ธ์๋ก ์ ๋ฌ๋ฉ๋๋ค.
์ด๋ฌํ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ ๋ชจ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ฉฐ, ๋น๋๊ธฐ๋ก ๋์ํฉ๋๋ค.
Promise.prototype.then
then ๋ฉ์๋๋ ๋ ๊ฐ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ต๋๋ค.
- ์ฒซ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์๋ ํ๋ก๋ฏธ์ค๊ฐ fulfilled ์ํ(resolve ํจ์๊ฐ ํธ์ถ๋ ์ํ)๊ฐ ๋๋ฉด ํธ์ถ๋๋ฉฐ ํ๋ก๋ฏธ์ค์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ต๋๋ค.
- ๋ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์๋ ํ๋ก๋ฏธ์ค๊ฐ rejected ์ํ(reject ํจ์๊ฐ ํธ์ถ๋ ์ํ)๊ฐ ๋๋ฉด ํธ์ถ๋๋ฉฐ ํ๋ก๋ฏธ์ค์ ์๋ฌ๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ต๋๋ค.
// fulfilled
new Promise(resolve => resolve('fulfilled'))
.then(v => console.log(v), e => console.error(e)); // fulfilled
// rejected
new Promise((_, reject) => reject(new Error('rejected')))
.then(v => console.log(v), e => console.error(e)); // Error: rejected
then ๋ฉ์๋๋ ์ธ์ ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค. ๋ง์ฝ then ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์๊ฐ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ฉด ๊ทธ ํ๋ก๋ฏธ์ค๋ฅผ ๊ทธ๋๋ก ๋ฐํํ๊ณ , ์ฝ๋ฐฑ ํจ์๊ฐ ํ๋ก๋ฏธ์ค๊ฐ ์๋ ๊ฐ์ ๋ฐํํ๋ฉด ๊ทธ ๊ฐ์ ์๋ฌต์ ์ผ๋ก resolve ๋๋ rejectํ์ฌ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑํด ๋ฐํํฉ๋๋ค.
Promise.prototype.catch
catch ๋ฉ์๋๋ ํ ๊ฐ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ผ๋ฉฐ ์ฝ๋ฐฑ ํจ์๋ ํ๋ก๋ฏธ์ค๊ฐ rejected ์ํ์ธ ๊ฒฝ์ฐ๋ง ํธ์ถ๋ฉ๋๋ค.
๋ํ, catch ๋ฉ์๋๋ then(undefined, onRejected)๊ณผ ๋์ผํ๊ฒ ๋์ํ๊ธฐ ๋๋ฌธ์ ์ธ์ ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค.
// rejected
new Promise((_, reject) => reject(new Error('rejected')))
.catch(e => console.log(e)); // Error: rejected
// rejected
new Promise((_, reject) => reject(new Error('rejected')))
.then(undefined, e => console.log(e)); // Error: rejected
Promise.prototype.finally
finally ๋ฉ์๋๋ ํ ๊ฐ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ์ต๋๋ค. finally ๋ฉ์๋์ ์ฝ๋ฐฑ ํฉ์๋ ํ๋ก๋ฏธ์ค์ ์ฑ๊ณต(fulfilled) ๋๋ ์คํจ(rejected)์ ์๊ด์์ด ๋ฌด์กฐ๊ฑด ํ ๋ฒ ํธ์ถ๋๋ฉฐ ์ธ์ ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค. ๋ฐ๋ผ์ ํ๋ก๋ฏธ์ค์ ์ํ์ ์๊ด์์ด ๊ณตํต์ ์ผ๋ก ์ํํด์ผ ํ ์ฒ๋ฆฌ ๋ด์ฉ์ด ์์ ๋ ์ ์ฉํฉ๋๋ค.
new Promise(() => {})
.finally(() => console.log('finally')); // finally
ํ๋ก๋ฏธ์ค์ ์๋ฌ ์ฒ๋ฆฌ
๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด๊ณผ ๋ฌ๋ฆฌ ํ๋ก๋ฏธ์ค๋ ์๋ฌ๋ฅผ ๋ฌธ์ ์์ด ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์๋ ์์ ์ ๋น๋๊ธฐ ํจ์ get์ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ฉฐ then, catch, finally ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ์ฒ๋ฆฌ๋ฅผ ์ํํฉ๋๋ค.
const promiseGet = url => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.send();
xhr.onload = () => {
if (xhr.status === 200) {
// ์ฑ๊ณต์ ์ผ๋ก ์๋ต์ ์ ๋ฌ๋ฐ์ผ๋ฉด resolve ํจ์๋ฅผ ํธ์ถํ๋ค.
resolve(JSON.parse(xhr.response));
} else {
// ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด reject ํจ์๋ฅผ ํธ์ถํ๋ค.
reject(new Error(xhr.status));
}
};
});
};
// promiseGet ํจ์๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
promiseGet('https://jsonplaceholder.typicode.com/posts/1')
.then(res => console.log(res))
.catch(err => console.error(err))
.finally(() => console.log('Bye!'));
์ด๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ์์ ๋ฐ์ํ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
then ๋ฉ์๋์ ๋ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์๋ก ์๋ฌ ์ฒ๋ฆฌ
const wrongUrl = 'https://jsonplaceholder.typicode.com/XXX/1';
// ๋ถ์ ์ ํ URL์ด ์ง์ ๋์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
promiseGet(wrongUrl).then(
res => console.log(res),
err => console.error(err)
); // Error: 404
// ์ฒซ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์์ ์๋ฌ ์บ์น X
promiseGet('https://jsonplaceholder.typicode.com/todos/1').then(
res => console.xxx(res),
err => console.error(err)
); // ๋ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์๋ ์ฒซ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์์์ ๋ฐ์ํ ์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ๋ค.
- then ๋ฉ์๋์ ๋ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์๋ ์ฒซ ๋ฒ์งธ ์ฝ๋ฐฑ ํจ์์์ ๋ฐ์ํ ์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ๊ณ ์ฝ๋๊ฐ ๋ณต์กํด์ ธ์ ๊ฐ๋ ์ฑ์ด ์ข์ง ์๋ค๋ ๋จ์ ์ด ์์
ํ๋ก๋ฏธ์ค์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋ catch๋ฅผ ์ฌ์ฉํด ์๋ฌ ์ฒ๋ฆฌ
const wrongUrl = 'https://jsonplaceholder.typicode.com/XXX/1';
// ๋ถ์ ์ ํ URL์ด ์ง์ ๋์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
promiseGet(wrongUrl)
.then(res => console.log(res))
.catch(err => console.error(err)); // Error: 404
const wrongUrl = 'https://jsonplaceholder.typicode.com/XXX/1';
// ๋ถ์ ์ ํ URL์ด ์ง์ ๋์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
promiseGet(wrongUrl)
.then(res => console.log(res))
.then(undefined, err => console.error(err)); // Error: 404
// then ๋ฉ์๋ ๋ด๋ถ ์๋ฌ๋ ์ฒ๋ฆฌ
promiseGet('https://jsonplaceholder.typicode.com/todos/1')
.then(res => console.xxx(res))
.catch(err => console.error(err)); // TypeError: console.xxx is not a function
- catch ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋ด๋ถ์ ์ผ๋ก then(undefined, onRejected)์ ํธ์ถํ์ฌ ์ฒ๋ฆฌ๋จ
- catch ๋ฉ์๋๋ฅผ ๋ชจ๋ then ๋ฉ์๋๋ฅผ ํธ์ถํ ์ดํ์ ํธ์ถํ๋ฉด ๋น๋๊ธฐ ์ฒ๋ฆฌ์์ ๋ฐ์ํ ์๋ฌ๋ฟ๋ง ์๋๋ผ then ๋ฉ์๋ ๋ด๋ถ์์ ๋ฐ์ํ ์๋ฌ๊น์ง ๋ชจ๋ ์บ์น ๊ฐ๋ฅ
- then ๋ฉ์๋๋ฅผ ํตํ ์๋ฌ ์ฒ๋ฆฌ์ ๋นํด ๊ฐ๋ ์ฑ์ด ์ข๊ณ ๋ช ํํ๊ธฐ ๋๋ฌธ์ catch ๋ฉ์๋๋ก ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๊ถ์ฅ๋จ
ํ๋ก๋ฏธ์ค ์ฒด์ด๋
ํ๋ก๋ฏธ์ค๋ then, catch, filnally ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ฅผ ํตํด ์ฝ๋ฐฑ ์ง์ฅ์ ํด๊ฒฐํฉ๋๋ค. ์๋ ์์ ๋ then -> then -> catch ์์๋ก ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
const url = 'https://jsonplaceholder.typicode.com';
// id๊ฐ 1์ธ post์ userId๋ฅผ ์ทจ๋
promiseGet(`${url}/posts/1`)
// ์ทจ๋ํ post์ userId๋ก user ์ ๋ณด๋ฅผ ์ทจ๋
.then(({ userId }) => promiseGet(`${url}/users/${userId}`))
.then(userInfo => console.log(userInfo))
.catch(err => console.error(err));
์ด์ฒ๋ผ then, catch, filnally ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ ์ธ์ ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ฏ๋ก ์ฐ์์ ์ผ๋ก ํธ์ถํ ์ ์์ผ๋ฉฐ ์ด๋ฅผ ํ๋ก๋ฏธ์ค ์ฒด์ด๋(promise chaining)์ด๋ผ๊ณ ํฉ๋๋ค.
ํ๋ก๋ฏธ์ค๋ ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ ํตํด ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌ๋ฐ์ ํ์ ์ฒ๋ฆฌ๋ฅผ ํ๋ฏ๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด์์ ๋ฐ์ํ๋ ์ฝ๋ฐฑ ์ง์ฅ์ด ๋ฐ์ํ์ง๋ ์์ง๋ง ํ๋ก๋ฏธ์ค๋ ์ฝ๋ฐฑ ํจํด์ ์ฌ์ฉํ๋ฏ๋ก ๊ฐ๋ ์ฑ์ด ์ข์ง ์์ต๋๋ค.
๋ฐ๋ผ์ ์ด ๋ฌธ์ ๋ ES8์์ ๋์ ๋ async/await์ ํตํด ํด๊ฒฐํ ์ ์์ต๋๋ค.
ํ๋ก๋ฏธ์ค์ ์ ์ ๋ฉ์๋
Promise๋ ์ฃผ๋ก ์์ฑ์ ํจ์๋ก ์ฌ์ฉ๋์ง๋ง ํจ์๋ ๊ฐ์ฒด์ด๋ฏ๋ก ๋ฉ์๋๋ฅผ ๊ฐ์ง ์ ์์๋๋ค. Promise๋ ๋ค์๊ณผ ๊ฐ์ด 5๊ฐ์ง ์ ์ ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
Promise.resolve / Promise.reject
Promise.resolve์ Promise.reject ๋ฉ์๋๋ ์ด๋ฏธ ์กด์ฌํ๋ ๊ฐ์ ๋ํํ์ฌ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
- Promise.resolve : ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ resolveํ๋ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑ
- Promise.reject : ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ rejectํ๋ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑ
// ๋ฐฐ์ด์ resolveํ๋ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑ 1
const resolvedPromise = Promise.resolve([1, 2, 3]);
resolvedPromise.then(console.log); // [1, 2, 3]
// ์์ ๋์ผ
const resolvedPromise = new Promise(resolve => resolve([1, 2, 3]));
resolvedPromise.then(console.log); // [1, 2, 3]
// ์๋ฌ ๊ฐ์ฒด๋ฅผ rejectํ๋ ํ๋ก๋ฏธ์ค๋ฅผ ์์ฑ1
const rejectedPromise = Promise.reject(new Error('Error!'));
rejectedPromise.catch(console.log); // Error: Error!
// ์์ ๋์ผ
const rejectedPromise = new Promise((_, reject) => reject(new Error('Error!')));
rejectedPromise.catch(console.log); // Error: Error!
Promise.all
Promise.all ๋ฉ์๋๋ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ชจ๋ ๋ณ๋ ฌ(parallel) ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํฉ๋๋ค.
Promise.all ๋ฉ์๋๋ ํ๋ก๋ฏธ์ค๋ฅผ ์์๋ก ๊ฐ๋ ๋ฐฐ์ด ๋ฑ์ ์ดํฐ๋ฌ๋ธ์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ๋ฌ๋ฐ์ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ ๋ชจ๋ fulfilled ์ํ๊ฐ ๋๋ฉด ๋ชจ๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด์ ์ ์ฅํด ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ์ ๋ฌ๋ฐ์ต๋๋ค.
// ์ฒ๋ฆฌ ์์๊ฐ ๋ณด์ฅ
const requestData1 = () => new Promise(resolve => setTimeout(() => resolve(1), 3000));
const requestData2 = () => new Promise(resolve => setTimeout(() => resolve(2), 2000));
const requestData3 = () => new Promise(resolve => setTimeout(() => resolve(3), 1000));
Promise.all([requestData1(), requestData2(), requestData3()])
.then(console.log) // [ 1, 2, 3 ] ⇒ ์ฝ 3์ด ์์
.catch(console.error);
// rejected๋๋ฉด ์ฆ์ ์ข
๋ฃ
Promise.all([
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 1')), 3000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 2')), 2000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 3')), 1000))
])
.then(console.log)
.catch(console.log); // Error: Error 3
// ํ๋ก๋ฏธ์ค๋ก ๋ํ
Promise.all([
1, // => Promise.resolve(1)
2, // => Promise.resolve(2)
3 // => Promise.resolve(3)
])
.then(console.log) // [1, 2, 3]
.catch(console.log);
- ์ฒ๋ฆฌ ์์๊ฐ ๋ณด์ฅ๋๊ธฐ ๋๋ฌธ์ ์ฒซ ๋ฒ์งธ ํ๋ก๋ฏธ์ค๊ฐ resolveํ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ถํฐ ์ฐจ๋ก๋๋ก ๋ฐฐ์ด์ ์ ์ฅ
- ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ฐฐ์ด์ ํ๋ก๋ฏธ์ค๊ฐ ํ๋๋ผ๋ rejected ์ํ๊ฐ ๋๋ฉด ๋๋จธ์ง ํ๋ก๋ฏธ์ค ์ํ๊ฐ fulfilled ์ํ๊ฐ ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃ
- ์ธ์๋ก ์ ๋ฌ๋ฐ์ ์ดํฐ๋ฌ๋ธ ์์๊ฐ ํ๋ก๋ฏธ์ค๊ฐ ์๋ ๊ฒฝ์ฐ Promise.resolve ๋ฉ์๋๋ฅผ ํตํด ํ๋ก๋ฏธ์ค๋ก ๋ํ
Promise.race
Promise.race ๋ฉ์๋๋ Promise.all ๋ฉ์๋์ ๋์ผํ๊ฒ ํ๋ก๋ฏธ์ค๋ฅผ ์์๋ก ๊ฐ๋ ๋ฐฐ์ด ๋ฑ์ ์ดํฐ๋ฌ๋ธ์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ง๋ง, Promise.all ๋ฉ์๋์ ๋ฌ๋ฆฌ ๋ชจ๋ ํ๋ก๋ฏธ์ค๊ฐ fulfilled ์ํ๊ฐ ๋๋ ๊ฒ์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ ๊ฐ์ฅ ๋จผ์ fulfilled ์ํ๊ฐ ๋ ํ๋ก๋ฏธ์ค์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ resolveํ๋ ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค.
Promise.race([
new Promise(resolve => setTimeout(() => resolve(1), 3000)), // 1
new Promise(resolve => setTimeout(() => resolve(2), 2000)), // 2
new Promise(resolve => setTimeout(() => resolve(3), 1000)) // 3
])
.then(console.log) // 3
.catch(console.log);
// rejected ์ํ
Promise.race([
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 1')), 3000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 2')), 2000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error 3')), 1000))
])
.then(console.log)
.catch(console.log); // Error: Error 3
- ์ธ์๋ก ์ ๋ฌ๋ ํ๋ก๋ฏธ์ค๊ฐ ํ๋๋ผ๋ rejected ์ํ๊ฐ ๋๋ฉด ์๋ฌ๋ฅผ rejectํ๋ ์๋ก์ด ํ๋ก๋ฏธ์ค๋ฅผ ์ฆ์ ๋ฐํ
Promise.allSettled
Promise.allSettled ๋ฉ์๋๋ ํ๋ก๋ฏธ์ค๋ฅผ ์์๋ก ๊ฐ๋ ๋ฐฐ์ด ๋ฑ์ ์ดํฐ๋ฌ๋ธ์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ผ๋ฉฐ ์ ๋ฌ๋ฐ์ ํ๋ก๋ฏธ์ค๊ฐ ๋ชจ๋ settled ์ํ๊ฐ ๋๋ฉด ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ฐํํฉ๋๋ค.
Promise.allSettled([
new Promise(resolve => setTimeout(() => resolve(1), 2000)),
new Promise((_, reject) => setTimeout(() => reject(new Error('Error!')), 1000))
]).then(console.log);
/*
[
{status: "fulfilled", value: 1},
{status: "rejected", reason: Error: Error! at <anonymous>:3:54}
]
*/
์ด์ฒ๋ผ Promise.allSettled ๋ฉ์๋๊ฐ ๋ฐํํ ๋ฐฐ์ด์๋ fulfilled ๋๋ rejected ์ํ์๋ ์๊ด์์ด Promise.allSettled ๋ฉ์๋๊ฐ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๋ชจ๋ ํ๋ก๋ฏธ์ค๋ค์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ๋ชจ๋ ๋ด๊ฒจ ์์ต๋๋ค.
- fulfilled ์ํ : ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ๋ฅผ ๋ํ๋ด๋ status ํ๋กํผํฐ์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ํ๋ด๋ value ํ๋กํผํฐ๋ฅผ ๊ฐ์ง
- rejected ์ํ : ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ๋ฅผ ๋ํ๋ด๋ status ํ๋กํผํฐ์ ์๋ฌ๋ฅผ ๋ํ๋ด๋ reason ํ๋กํผํฐ๋ฅผ ๊ฐ์ง
๋ง์ดํฌ๋กํ์คํฌ ํ
ํ๋ก๋ฏธ์ค์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์๋ ํ์คํฌ ํ๊ฐ ์๋๋ผ ๋ง์ดํฌ๋กํ์คํฌ ํ์ ์ ์ฅ๋ฉ๋๋ค.
- ํ ์คํฌ ํ์๋ ๋ณ๋์ ํ
- ํ๋ก๋ฏธ์ค์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์ ์ฝ๋ฐฑ ํจ์๊ฐ ์ผ์ ์ ์ฅ
- ํ์คํฌ ํ๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์
ํ๋ก๋ฏธ์ค์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋ ์ธ์ ๋น๋๊ธฐ ํจ์์ ์ฝ๋ฐฑ ํจ์๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ํ์คํฌ ํ์ ์ผ์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ ์๋ ์์ ๋ 2 -> 3 -> 1์ ์์ผ๋ก ์ถ๋ ฅ๋ฉ๋๋ค.
setTimeout(() => console.log(1), 0);
Promise.resolve()
.then(() => console.log(2))
.then(() => console.log(3));
์ด์ฒ๋ผ ์ด๋ฒคํธ ๋ฃจํ๋ ์ฝ ์คํ์ด ๋น๋ฉด ๋จผ์ ๋ง์ดํฌ๋กํ์คํฌ ํ์์ ๋๊ธฐํ๊ณ ์๋ ํจ์๋ฅผ ๊ฐ์ ธ์ ์คํํ๊ณ ์ดํ ๋ง์ดํฌ๋กํ์คํฌ ํ๊ฐ ๋น๋ฉด ํ์คํฌ ํ์์ ๋๊ธฐํ๊ณ ์๋ ํจ์๋ฅผ ๊ฐ์ ธ์ ์คํํฉ๋๋ค.
fetch
fetch ํจ์๋ XMLHttpRequest ๊ฐ์ฒด์ ๋ง์ฐฌ๊ฐ์ง๋ก HTTP ์์ฒญ ์ ์ก ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ Web API ์ด๋ฉฐ
XMLHttpRequest ๊ฐ์ฒด๋ณด๋ค ์ฌ์ฉ๋ฒ์ด ๊ฐ๋จํ๊ณ ํ๋ก๋ฏธ์ค๋ฅผ ์ง์ํ๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑ ํจํด์ ๋จ์ ์์
์์ ๋กญ์ต๋๋ค.
const promise = fetch(url, [, options])
fetch ํจ์์๋ HTTP ์์ฒญ์ ์ ์กํ URL๊ณผ HTTP ์์ฒญ ๋ฉ์๋, HTTP ์์ฒญ ํค๋, ํ์ด๋ก๋ ๋ฑ์ ์ค์ ํ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ฉฐ HTTP ์๋ต์ ๋ํ๋ด๋ Response ๊ฐ์ฒด๋ฅผ ๋ํํ Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => console.log(response));
๋ฐ๋ผ์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋ then์ ํตํด ํ๋ก๋ฏธ์ค๊ฐ resolveํ Response ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ์ ์ ์์ผ๋ฉฐ Response๊ฐ์ฒด๋ HTTP ์๋ต์ ๋ํ๋ด๋ ๋ค์ํ ํ๋กํผํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
fetch ํจ์์ ์๋ฌ ์ฒ๋ฆฌ
fetch ํจ์๋ฅผ ์ฌ์ฉํ ๋๋ ์๋ฌ ์ฒ๋ฆฌ์ ์ฃผ์ํด์ผ ํฉ๋๋ค.
- fetch ํจ์๊ฐ ๋ฐํํ๋ ํ๋ก๋ฏธ์ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก 404๋ 500์ ๊ฐ์ HTTP ์๋ฌ๊ฐ ๋ฐ์ํด๋ ์๋ฌ๋ฅผ rejectํ์ง ์๊ณ ๋ถ๋ฆฌ์ธ ํ์ ์ ok ์ํ๋ฅผ false๋ก ์ค์ ํ Response ๊ฐ์ฒด๋ฅผ resolveํจ
- ์คํ๋ผ์ธ ๋ฑ์ ๋คํธ์ํฌ ์ฅ์ ๋ CORS ์๋ฌ์ ์ํด ์์ฒญ์ด ์๋ฃ๋์ง ๋ชปํ ๊ฒฝ์ฐ์๋ง ํ๋ก๋ฏธ์ค๋ฅผ rejectํจ
๋ฐ๋ผ์ fetch ํจ์๋ฅผ ์ฌ์ฉํ ๋๋ ๋ค์๊ณผ ๊ฐ์ด fetch ํจ์๊ฐ ๋ฐํํ ํ๋ก๋ฏธ์ค๊ฐ resolveํ ๋ถ๋ฆฌ์ธ ํ์ ์ ok ์ํ๋ฅผ ํ์ธํด ๋ช ์์ ์ผ๋ก ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ํ์๊ฐ ์์ต๋๋ค.
const wrongUrl = 'https://jsonplaceholder.typicode.com/XXX/1';
// ๋ถ์ ์ ํ URL์ด ์ง์ ๋์๊ธฐ ๋๋ฌธ์ 404 Not Found ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
fetch(wrongUrl)
// response๋ HTTP ์๋ต์ ๋ํ๋ด๋ Response ๊ฐ์ฒด๋ค.
.then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(todo => console.log(todo))
.catch(err => console.error(err));
*axios๋ ๋ชจ๋ HTTP ์๋ฌ๋ฅผ rejectํ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ์ฌ ๋ชจ๋ ์๋ฌ๋ฅผ catch์์ ์ฒ๋ฆฌํ ์ ์์ด ํธ๋ฆฌํ๋ฉฐ ์ธํฐ์ ํฐ,
์์ฒญ ์ค์ ๋ฑ fetch๋ณด๋ค ๋ค์ํ ๊ธฐ๋ฅ์ ์ง์ํจ
GET ์์ฒญ
request.get('https://jsonplaceholder.typicode.com/todos/1')
.then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(todos => console.log(todos))
.catch(err => console.error(err));
// {userId: 1, id: 1, title: "delectus aut autem", completed: false}
POST ์์ฒญ
request.post('https://jsonplaceholder.typicode.com/todos', {
userId: 1,
title: 'JavaScript',
completed: false
}).then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(todos => console.log(todos))
.catch(err => console.error(err));
// {userId: 1, title: "JavaScript", completed: false, id: 201}
PATCH ์์ฒญ
request.patch('https://jsonplaceholder.typicode.com/todos/1', {
completed: true
}).then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(todos => console.log(todos))
.catch(err => console.error(err));
// {userId: 1, id: 1, title: "delectus aut autem", completed: true}
DELETE ์์ฒญ
request.delete('https://jsonplaceholder.typicode.com/todos/1')
.then(response => {
if (!response.ok) throw new Error(response.statusText);
return response.json();
})
.then(todos => console.log(todos))
.catch(err => console.error(err));
// {}
[์ถ์ฒ] ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive
'JavaScript > ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JavaScript] ์๋ฌ ์ฒ๋ฆฌ (0) | 2022.08.19 |
---|---|
[JavaScript] ์ ๋๋ ์ดํฐ์ async/await (0) | 2022.08.17 |
[JavaScript] REST API (0) | 2022.08.16 |
[JavaScript] Ajax (0) | 2022.08.15 |
[JavaScript] ํ์ด๋จธ (0) | 2022.08.13 |
- Total
- Today
- Yesterday
- ๋ ์์ปฌ ํ๊ฒฝ
- ๋ฐฑ์ค javascript
- ๋์์ธ ํจํด
- map
- ์ ์ญ ๋ณ์
- ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ
- JavaScript
- ํ๋ก๊ทธ๋๋จธ์ค
- ๋คํธ์ํฌ
- http
- ํฌํฌ์ธํฐ
- ์๋ฐ์คํฌ๋ฆฝํธ
- ์ด์์ฒด์
- TDD
- ์๋ฐ
- ๋ฐฑ์ค
- Baekjoon
- ์ฝ๋ฉํ ์คํธ
- ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ
- ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ deep dive
- ์นด์นด์ค ์ธํด
- 2019 ์นด์นด์ค ๊ฐ๋ฐ์ ๊ฒจ์ธ ์ธํด
- ํ๋กํผํฐ
- fp
- ์๊ณ ๋ฆฌ์ฆ
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ
- git
- ํ๋กํ ์ฝ
- ์ด๋ถํ์
- ๋ฐฑ์ค node.js
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |