Promise : ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ํจํด, ์ฝ๋ฐฑํจ์์ ๋จ์ ์ ๋ณด์ํ๋ฉฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์์ ์ ๋ช ํํ๊ฒ ํํํ ์ ์๋ค.
Promise๋ ์ ๋ง๋ค์ด์ก์๊น?
๊ณ๊ธฐ๋ฅผ ์๊ธฐ ์ํด์๋ ๊ธฐ์กด ๋น๋๊ธฐ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋ฐฑํจํด์ ๋จผ์ ์์๋ด์ผํ๋ค.
์ฝ๋ฐฑ ํจํด์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ์ํ์ฌ ์ฌ์ฉํ๋ ํจํด์ด๋ค.
XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ์์ฒญ์ ํ๊ณ ์๋ต์ ๋ฐ๋ ํํ์ด๋ค.
๋ค์์ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ์์ฒญ์ ํ์ฌ ์ฝ์๋ก ์๋ต์ ๋ฐ๋ ์์์ด๋ค.
index.js
const get = (url) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url); //url์ GET ์์ฒญ ๋ฉ์๋๋ก ๋ณด๋ผ๊ฒ์ด๋ผ๋ ์ค์
xhr.send(); // ์๋ฒ์ ์์ฒญ ๋ณด๋ด๊ธฐ
xhr.onload = () => {
//์๋ต ์ํ์ ๋ฐ๋ฅธ ์๋ต ๊ฒฐ๊ณผ ์ฝ์๋ก ๋ฐ๊ธฐ
if (xhr.status === 200) {
console.log(JSON.parse(xhr.response)); //์๋ต๊ฒฐ๊ณผ
} else {
console.error(`${xhr.status} ${xhr.statusText}`);
}
};
};
get("https://jsonplaceholder.typicode.com/posts/1");
console๋ก ๋ฐ์ ์๋ต ๊ฒฐ๊ณผ
์ด์ ๊ฐ์ด console.log๋ฅผ ํตํด์๋ ์๋ต๊ฒฐ๊ณผ๋ฅผ ์ ๋ฐ์ ์ ์๋ค.
ํ์ง๋ง ์๋ต๊ฒฐ๊ณผ๋ฅผ ์ค์ง์ ์ผ๋ก ์จ๋จน์ด์ผํ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ๋ฐ์๋ณด๊ฒ ๋ค.
const get = (url) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url); //url์ GET ์์ฒญ ๋ฉ์๋๋ก ๋ณด๋ผ๊ฒ์ด๋ผ๋ ์ค์
xhr.send(); // ์๋ฒ์ ์์ฒญ ๋ณด๋ด๊ธฐ
xhr.onload = () => {
//์๋ต ์ํ์ ๋ฐ๋ฅธ ์๋ต ๊ฒฐ๊ณผ ์ฝ์๋ก ๋ฐ๊ธฐ
if (xhr.status === 200) {
return JSON.parse(xhr.response);
} else {
console.error(`${xhr.status} ${xhr.statusText}`);
}
};
};
const result = get("https://jsonplaceholder.typicode.com/posts/1");
console.log(result); // ์๋ต๊ฒฐ๊ณผ๊ฐ ๋์ฌ๊น?
์์ฝ๊ฒ๋ ์๋ต๊ฒฐ๊ณผ๋ undefined์ด๋ค.
์ ์ด๋ฌํ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ ๊ฒ์ผ๊น?
์ด๋ฅผ ์๊ธฐ ์ํด์ ๋น๋๊ธฐ ์ฝ๋์ ์คํ ์์ ์ ์์์ผํ๋ค.
๋น๋๊ธฐ ํจ์๋ ๋น๋๊ธฐ์ ์ธ ์ฝ๋๋ฅผ ํฌํจํ๊ณ ์์ ๋ ๋น๋๊ธฐ ํจ์๋ผ๊ณ ํ๋ค.
์ get(url)ํจ์๋ ๋น๋๊ธฐ ํจ์์ด๋ค.
์ด์ ๋ xhr.onload ์ด๋ฒคํธ ํธ๋ค๋ฌ๊ฐ ๋น๋๊ธฐ์ ์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
๋น๋๊ธฐ ์ฝ๋๋ ๋ชจ๋ ์ฝ๋๊ฐ ์คํ๋๊ณ ๋ ๋ค์ ์คํ์ด ๋๋ค.
์ฝ๋๊ฐ ์์ฐจ์ ์ผ๋ก ์คํ๋ ๋ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ๋ง๋๊ฒ ๋๋ฉด ํด๋น ์ฝ๋๋ ํ์คํฌ ํ๋ก ์ฎ๊ฒจ์ง๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ชจ๋ ์ฝ๋๊ฐ ์คํ๋๊ณ ๋ ๋ค์ ํ์คํฌ ํ์์ ์คํ ์ปจํ
์คํธ๋ก ์ฎ๊ฒจ์ ธ ๊ทธ์ ์์ผ ํด๋น ์ฝ๋๊ฐ ์คํ์ด ๋๋ค.
xhr.onload ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋ชจ๋ ํจ์๊ฐ ์คํ๋์ด ์ข
๋ฃ๊ฐ ๋ ์ดํ์ ์คํ๋๋ค๋ ์๊ธฐ์ด๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ ํจ์์์ ๋ฐํ๊ฐ์ ๋ฐ์ผ๋ คํด๋ ๋ฐ์ ์๊ฐ ์๋ ๊ฒ์ด๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ์ฝ๋ฐฑ ํจํด์ด ๋ฑ์ฅํ๊ฒ ๋๋ค.
๋น๋๊ธฐ ํจ์์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ๋ฐ๊ธฐ ์ํด์ ๋น๋๊ธฐ ํจ์๋ด๋ถ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
index.js
const get = (url, successCallback, failureCallback) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url); //url์ GET ์์ฒญ ๋ฉ์๋๋ก ๋ณด๋ผ๊ฒ์ด๋ผ๋ ์ค์
xhr.send(); // ์๋ฒ์ ์์ฒญ ๋ณด๋ด๊ธฐ
xhr.onload = () => {
//์๋ต ์ํ์ ๋ฐ๋ฅธ ์๋ต ๊ฒฐ๊ณผ ์ฝ์๋ก ๋ฐ๊ธฐ
if (xhr.status === 200) {
successCallback(JSON.parse(xhr.response));
} else {
failureCallback(xhr.status);
}
};
};
const p = document.querySelector("p");
get(
"https://jsonplaceholder.typicode.com/posts/1",
(success) => {
p.textContent = JSON.stringify(success); //๊ฐ์ฒด๋ฅผ ๋ฌธ์์ด๋ก ๋ฐ๊ธฐ์ํ์ฌ
},
(failure) => {
p.textContent = JSON.stringify(failure);
}
);
๋ธ๋ผ์ฐ์ ์๋ต ๊ฒฐ๊ณผ
getํจ์์ ์ธ์(successCallback)๋ก ์ฝ๋ฐฑํจ์๋ฅผ ๋ฃ์ด์ฃผ์ด ์๋ต๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ ๋ฉ์ปค๋์ฆ์ด๋ค.
ํ์ง๋ง ์์ฒ๋ผ ์๋ต๊ฒฐ๊ณผ๋ฅผ ์ฝ๋ฐฑํจ์์์ ๋ฐ์์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋ ์ฑ์ ๋ฌธ์ ๊ฐ ์๋ ์ฝ๋ฐฑ ์ง์ฅ์ด๋ผ๋ ๋ฌธ์ ๋ฅผ ๋ฐ์์ํจ๋ค.
์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
index.js
const get = (url, successCallback, failureCallback) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url); //url์ GET ์์ฒญ ๋ฉ์๋๋ก ๋ณด๋ผ๊ฒ์ด๋ผ๋ ์ค์
xhr.send(); // ์๋ฒ์ ์์ฒญ ๋ณด๋ด๊ธฐ
xhr.onload = () => {
//์๋ต ์ํ์ ๋ฐ๋ฅธ ์๋ต ๊ฒฐ๊ณผ ์ฝ์๋ก ๋ฐ๊ธฐ
if (xhr.status === 200) {
successCallback(JSON.parse(xhr.response));
} else {
failureCallback(xhr.status);
}
};
};
const h1 = document.querySelector("h1");
const p = document.querySelector("p");
get(
"https://jsonplaceholder.typicode.com/posts/1",
(success) => {
h1.textContent = JSON.stringify(success);
get(
`https://jsonplaceholder.typicode.com/users/${success.userId}`,
(userInfo) => {
p.textContent = JSON.stringify(userInfo);
}
);
},
(failure) => {
h1.textContent = JSON.stringify(failure);
}
);
๋ธ๋ผ์ฐ์ ์๋ต๊ฒฐ๊ณผ
ํ์ง๋ง ์๋ต๊ฒฐ๊ณผ๋ฅผ ํ ๋๋ฒ๋ง ๋ฐ์์ ์ฌ์ฉํ๋คํ๋ฉด ์ฝ๋ฐฑํจํด๋ ๋์์ง์์ ๊ฒ์ด๋ค.
๋ค๋ง promise๊ฐ ์กฐ๊ธ ๋ ์ฐ๊ธฐ ํธํ๊ณ ์์ ๊ฐ์ ๋จ์ ์ ์ปค๋ฒํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌํ์ฌ ์ด๋ฌํ ์ฝ๋ฐฑ ํจํด์ ๋ฌธ์ ์ ์ ํ๊ธฐ ์ํด ํ์ํ ๊ฒ์ด Promise์ด๋ค.
์ฝ๋ฐฑ ํจํด์ ๋ฌธ์ ์
- ์ฝ๋ฐฑ ์ง์ฅ
- ์๋ฌ ์ฒ๋ฆฌ ๊ณค๋
Promise๋ ES6์ ๋์ ๋ ECMAscript ์ฌ์์ ์ ์๋ ๋นํธ์ธ ๊ฐ์ฒด์ด๋ค.
new Promise((resolve,reject) => resolve("success"),reject("failure"))
Promise ์์ฑ์ํจ์๋ฅผ new ์ฐ์ฐ์์ ํจ๊ป ํธ์ถํ๋ฉด ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
Promise ์์ฑ์ ํจ์๋ ์ด๋ ํ ๊ฐ์ ๋ฐํํ๋ ๊ฒ์ด ์๋ ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
Promise ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ํ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด์ด๋ค.
Promise ์์ฑ์ ํจ์๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ์ผ๋ฉฐ ์ฝ๋ฐฑ ํจ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
์ฒซ๋ฒ์งธ ์ฝ๋ฐฑํจ์ resolve๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ์ ๋ ํธ์ถ๋๋ ํจ์์ด๋ค.
์ฝ๋ฐฑํจ์ resolve()์ ์ธ์(success)๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ์ ๋ ์ ๋ฌ๋๋ ๊ฐ์ด๋ค.
๋๋ฒ์งธ ์ฝ๋ฐฑํจ์ reject๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ์ ๋ ํธ์ถ๋๋ ํจ์์ด๋ค.
์ฝ๋ฐฑํจ์ reject()์ ์ธ์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ์ ๋ ์ ๋ฌ๋๋ ๊ฐ์ด๋ค.
index.js
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(JSON.parse(xhr.response));
else reject(new Error(xhr.status));
};
});
};
promiseGet("https://jsonplaceholder.typicode.com/posts/1");
์ ์์ ์์๋ ๋ณ ๋ค๋ฅธ ์๋ฌ๊ฐ ์์ด ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ์ผ๋ resolve()์ฝ๋ฐฑํจ์๊ฐ ํธ์ถํ๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ต๊ฐ์ promise ๊ฐ์ฒด์ ์ ๋ฌํ๋ค.
Promise๋ ๋น๋๊ธฐ ์ฝ๋ฐฑ ํจ์ ํจํด์ ์๋ฌ์ฒ๋ฆฌ์ ์ฝ๋ฐฑ ์ง์ฅ์ ๋จ์ ์ ๋ณด์ํด์ค๋ค๊ณ ํ์๋ค.
promise ๊ฐ์ฒด์ ํ์์ฒ๋ฆฌ ๋ฉ์๋๊ฐ ๋ฐ๋ก ์ด ๋จ์ ๋ค์ ๋ณด์ํด์ค๋ค.
๋น๋๊ธฐ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ๋ (resolve) ์คํจํ๋ (reject) ํ๋ก๋ฏธ์ค๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ ๋ฌ๋ ์๋ต๊ฐ์ ํ์์ฒ๋ฆฌ๋ฉ์๋์ ๋๊ฒจ์ค ์ ์๋ค.
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(JSON.parse(xhr.response));
else reject(new Error(xhr.status));
};
}).then((response) => console.log(response));
};
promiseGet("https://jsonplaceholder.typicode.com/posts/1");
ํ์ ์ฒ๋ฆฌ ๋ฉ์๋ then์ ์๋ต๊ฐ์ ์ฝ๋ฐฑํจ์์ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ค.
(์ฃผ์ : ์ฝ๋ฐฑํจ์ ์์ฒด๊ฐ ์๋ ์ฝ๋ฐฑํจ์์ ์ธ์)
๊ทธ๋ฆฌ๊ณ then๋ฉ์๋๋ ๋ค์ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
then๋ฉ์๋์ ์ฝ๋ฐฑํจ์๊ฐ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค๋ฉด ํด๋น ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํด์ฃผ๊ณ ,
ํ๋ก๋ฏธ์ค๊ฐ ์๋ ๊ฐ์ ๋ฐํํ๋ฉด ์๋ฌต์ ์ผ๋ก ๊ทธ ๊ฐ์ resolve๋ rejectํด์ฃผ์ด ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
(์ด์ฐ๋ฌ๋ then()์ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.)
//1๋ฒ
new Promise((res, rej) => {
res(1);
rej("error");
}).then(
(response) =>
new Promise((res, rej) => {
res(response);
rej("error");
})
);
1๋ฒ์์ ์ฒ๋ผ then๋ฉ์๋์ ์ฝ๋ฐฑํจ์๊ฐ promise๋ฅผ ๋ฐํํ๋ฉด ํด๋น Promise๋ฅผ ๋ฐํ๋ฐ๊ฒ ๋๋ ๊ฒ์ด๊ณ ,
//2๋ฒ
new Promise((res, rej) => {
res(1);
rej("error");
})
.then((response) => response + 1)
.then((result) => console.log(result));
2๋ฒ์์ ์ฒ๋ผ then๋ฉ์๋์ ์ฝ๋ฐฑํจ์๊ฐ promise๊ฐ ์๋ ๊ฐ์ ๋ฐํํด๋ ์๋ฌต์ ์ผ๋ก ํ๋ก๋ฏธ์ค๋ก ์ฒ๋ฆฌํด์ค๋ค.
์ด๋ฌํ ์ด์ ๋ก ๊ณ์ํด์ ์๋ต๊ฐ์ ์ ๋ฌํ ์ ์๋ ๊ฒ์ด๋ค.
์ด๋ฅผ ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ด๋ผํ๋ค.
๋ํ ์ด๋ฌํ ํ๋ก๋ฏธ์ค ์ฒด์ด๋์ด ๋ฐ๋ก ์ฝ๋ฐฑ ์ง์ฅ์ ๋จ์ ์ ํด๊ฒฐํด์ค๋ค.
ํ์์ฒ๋ฆฌ๋ฉ์๋ catch๋ ์๋ฌ๋ฅผ ์บ์นํด์ค๋ค.
๊ธฐ์กด then๋ฉ์๋์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจ๋ ์๋ต๊ฐ์ ๋ฐ๊ธฐ ์ํด์๋ reject(๋๋ฒ์งธ ์ฝ๋ฐฑํจ์)๋ก ๋ฐ์์ค์ผํ๋ค.
new Promise((res, rej) => {
res(1);
rej("error");
})
ํ์ง๋ง catch๋ reject๋ ๊ฐ๋ง์ ์ ๋ฌ๋ฐ๋๋ค.
new Promise((res) => {
res(1);
})
.then((result) => console.log(result))
.catch((e) => console.log(e));
๋๋ฌธ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์คํจํ ๊ฐ์ catch๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์จ์ ์ด๋ค.
finally ๋ฉ์๋๋ ๋จ ํ๊ฐ์ ์ฝ๋ฐฑํจ์๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
์ด๋ resolve์ด๊ฑด reject์ด๊ฑด ๋ง์ง๋ง์ ๋ฌด์กฐ๊ฑด ํ๋ฒ ํธ์ถ๋๋ค.
๋ํ finally ๋ฉ์๋๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค.
new Promise((res) => {
res(1);
})
.then((result) => console.log(result))
.catch((e) => console.log(e))
.finally(() => console.log("Finally!"));
๋ชจ๋ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋๋ฅผ ์์๋ณด์๋๋ฐ ์ด ๋ฉ์๋๋ค์ ๋ชจ๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ค๋ ์ฌ์ค์ ์ ์ ์๋ค.
๋ํ ํ๋ก๋ฏธ์ค๊ฐ ์๋๋ผ๋ฉด ์ด ๋ฉ์๋๋ค์ ์๋ต๊ฐ์ ์ฒ๋ฆฌํ์ง ๋ชปํ๋ค๋ ๊ฒ๋ ์ ์ ์์๋ค.