Callback,Promise,async/await
ํ์ต ํค์๋
Callback ํจ์
Promise
async/await
Callback ํจ์
๋ค๋ฅธํจ์์ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋๋ ํจ์๋ฅผ ์๋ฏธ
์ด๋ค ์์ ์ด ๋๋๊ฑฐ๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ํธ์ถ๋๋ ํจ์๋ฅผ ์๋ฏธ
์ผ๋ฐ์ ์ผ๋ก ๋น๋๊ธฐ ํจ์ ์ฒ๋ฆฌ๊ฐ ๋๋๋ฉด ์คํํ ์์ ์ผ๋ก ์ฝ๋ฐฑํจ์๋ฅผ ์ ๋ฌ
๐ค ์ฝ๋ฐฑํจ์๊ฐ ์ฌ์ฉ๋๋ ์ด์ ๋?
์๋ฐ์คํฌ๋ฆฝํธ๋ ๋๊ธฐ์ ๋ฐฉ์
์ผ๋ก ํ๋ฒ์ ํ๊ฐ์ง ์ผ๋ง ์ฒ๋ฆฌํ๋ค. ์ฆ, ํจ์๊ฐ ํธ์ถ ๋๋ ์์๋๋ก ์์ฐจ์ ์ผ๋ก ์ฝ๋๊ฐ ์คํ ๋๋ค. ๊ทธ๋ฌ๋, ๋คํธ์ํฌ ์์ฒญ๊ณผ ๊ฐ์ด ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์
์ ์ํ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ํ์ฌ ์คํ ์ค์ธ ์ฝ๋๊ฐ ์ข
๋ฃ ๋์ง ์์ ์ํ๋ผํด๋ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค์ ์ฝ๋๋ฅผ ๋ฐ๋ก ์คํํ๋๋ก ๋น๋๊ธฐ ๋ฐฉ์
์ผ๋ก ์ฝ๋๋ฅผ ์คํ์ํจ๋ค. ์ด์ ๊ฐ์ด ์์๊ฐ ๋ณด์ฅ ๋์ง ์๋ ์ํฉ์์ ์์๊ฐ ๋ณด์ฅ๋๊ฑฐ๋, ๋น๋๊ธฐ ํจ์ ์ฒ๋ฆฌ๊ฐ ๋๋๋ฉด ์คํํ ์์
์ ์ฝ๋ฐฑํจ์์ ์ ๋ฌํ์ฌ ์ฌ์ฉํ๋ค.
๐ฉ๐ปโ๐ป ์ฝ๋ฐฑํจ์ ์ฌ์ฉํด๋ณด์
function task1() {
console.log('์ฒซ๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
}
function task2() {
// โ
์์๊ฐ ๋ณด์ฅ๋์ง ์๋ ํจ์ ๋ก์ง์ด ์๋ค๋ฉด?
setTimeout(() => {
console.log('๋๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
}, 2000);
}
function task3() {
console.log('์ธ๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
}
function task4() {
console.log('๋ค๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
}
task1();
task2();
task3();
task4();
์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด task2
ํจ์๋ด๋ถ์๋ ๋น๋๊ธฐ๋ก ๋์ํ๋ ํจ์ setTimeout
์กด์ฌํ๋ค. ๋ด๊ฐ ์๋ํ๋๊ฑด task1 โ task2 โ task3 โ task4
์์ผ๋ก ๋์ํ๊ธธ ์ํ๋ค. ๊ทธ๋ฌ๋ task1 โ task3 โ task4 โ task2
์์ผ๋ก ๋์๋์ด ์๋ํ ๋ฐฉํฅ๊ณผ๋ ๋ฌ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ฝ๋ฐฑํจ์๋ฅผ ์ฌ์ฉํด์ ์์๋ฅผ ๋ณด์ฅํ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์!
function task1(callback) {
console.log('์ฒซ๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
callback();
}
function task2(callback) {
// โ
์์๊ฐ ๋ณด์ฅ๋์ง ์๋ ํจ์ ๋ก์ง์ด ์๋ค๋ฉด?
setTimeout(() => {
console.log('๋๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
callback();
}, 2000);
}
function task3(callback) {
console.log('์ธ๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
callback();
}
function task4(callback) {
console.log('๋ค๋ฒ์งธ๋ก ์คํ๋์ด์ผ ํ๋ ํจ์');
callback();
}
task1(() => {
task2(() => {
task3(() => {
task4(() => {
console.log('๋ชจ๋ ํจ์ ์คํ ์๋ฃ!!');
});
});
});
});
๐ฑ ์ฝ๋ฐฑ์ง์ฅ(Callback hell)

๋น๋๊ธฐ ํจ์๊ฐ ์ฒ๋ฆฌ๊ฐ ๋๋๋ฉด ์คํ๋์ด์ผ ํ ์ฝ๋ฐฑํจ์๋ค์ด ์ค์ฒฉ๋์ด indent(๋ค์ฌ์ฐ๊ธฐ)๊ฐ ์ ์ ๊น์ด์ง๋ ํํ๋ก ๋๊ณ ์ด์๊ฐ์ด ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ์์ข์์ง๊ฒ ๋๋ ์ํฉ์
์ฝ๋ฐฑ์ง์ฅ
,Callback hell
์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
Promise
์ฝ๋ฐฑํจ์์ ๋จ์ ์ ๋ณด์ํ๋ฉฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ณด๋ค ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ES6 ์ถ๊ฐ๋ ๋ฌธ๋ฒ
์๋ฐ์คํฌ๋ฆฝํธ์ ํน์ ๊ฐ์ฒด (
๋น๋๊ธฐ ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ด๊ณ ์๋ ๊ฐ์ฒด
)๋๊ฐ์ ์ฝ๋ฐฑํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌ๋ฐ๋๋ฐ, ์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋
resolve ํจ์
์ ์์ ์ด ์คํจํ์๋ ์๋ฌ๋ฅผ ๋ฐํํ๋reject ํจ์
๊ฐ ์๋ค.
๊ธฐ๋ณธ ๋ฌธ๋ฒ
new ํค์๋๋ฅผ ํตํด ์์ฑ
resolve, reject๋ฅผ ๋งค๊ฐ๋ณ์๋ก ํ๋ ํจ์ ์ ๋ฌ๋ฐ๋๋ค.
resolve
: ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ฑ๊ณตํ์ ๋ ํธ์ถํ ํจ์reject
: ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ์ ๋ ํธ์ถํ ํจ์
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success');
reject('fail');
}, 2000);
});
promise
.then((res) => {
console.log(res); // success
})
.catch((err) => {
console.log(err); // fail
});
๐ Promise 3๊ฐ์ง ์ํ
pending(๋๊ธฐ)
new Promise()
๋ฉ์๋๋ก ํธ์ถํ๋ฉด ๋๊ธฐ ์ํ๊ฐ ๋๋ค.๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์์ง ์๋ฃ ๋์ง ์์ ์ํ
fulfilled(์ดํ)
๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋์ด ํ๋ก๋ฏธ์ค๊ฐ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํด์ค ์ํ
then
์ ํตํด ์ฒ๋ฆฌ๊ฐ์ ์ ๋ฌ๋ฐ์ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ ๊ฐ๋ฅ
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success'); // ๋น๋๊ธฐ ํจ์๊ฐ ์๋ฃ๋๋ฉด resolve()ํจ์ ์คํ
}, 2000);
});
promise.then((res) => {
// resolve()์ ๊ฒฐ๊ณผ๊ฐ ์ฝ๋ฐฑํจ์์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ์ฌ์ฉ ๊ฐ๋ฅ
console.log(res);
});
rejected(์คํจ)
๋น๋๊ธฐ ์์ ์ด ์คํจํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ํ
์คํจ์ํ๊ฐ ๋๋ฉด ์คํจํ ์ด์ ๋ฅผ
catch
๋ก ๋ฐ์ ์ ์๋ค.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('fail'); // ๋น๋๊ธฐ ํจ์๊ฐ ์คํจํ๋ฉด reject()ํจ์ ์คํ
}, 2000);
});
promise.catch((res) => {
// reject()์ ์คํจ์ด์ ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ ๊ฐ๋ฅ
console.log(res);
});
โ๏ธ Promise ์ฒด์ด๋
Promise ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ฐ๊ฒฐ์ง์ด ์ฌ์ฉํ๋ ์ํฉ
promise
.then((value) => {
console.log(value);
})
.catch((error) => {
console.log(error);
});
๐ฑ Promise hell๋ ์กด์ฌํ๋ค
์๋ ์ฝ๋์ ๊ฐ์ด then ๋ฉ์๋๋ฅผ ํตํด ๊ฒฐ๊ณผ๊ฐ์ ์ธ์๋ก ๋ฐ์์์ ์์ ์ ์ํํ๊ณ , ๋ค์ then ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ , ๋ then,then,... ์ ๊ฐ์ด ์์ ์ด ๋ฌด์ํ ๊ธธ์ด์ง๊ธฐ ๋๋ฌธ์ ์ฝ๋ฐฑ์ง์ฅ์ ์ด์ด
ํ๋ก๋ฏธ์ค ํฌ
์ด๋ผ๋ ํํ๋ ์๋ค.
function sum(num) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof num === 'number') {
resolve(num + 1);
} else {
reject('num์ด ์ซ์๊ฐ ์๋๋๋ค.');
}
}, 2000);
});
return promise;
}
sum(0).then((result) => {
console.log(`๊ฒฐ๊ณผ : ${result}`);
sum(result).then((result2) => {
console.log(`๊ฒฐ๊ณผ : ${result2}`);
sum(result2).then((result3) => {
console.log(`๊ฒฐ๊ณผ : ${result3}`);
sum(result3).then((result4) => {
console.log(`๊ฒฐ๊ณผ : ${result4}`);
});
});
});
});
๐ฅ return ํ์ฉํด Promise hell ํด๊ฒฐํ์
return๋ก
promise
๊ฐ์ฒด๋ฅผ ๋ฐํํด์ ์ฌ์ฉํ๋ฉด hell์์ ๋ฒ์ด๋ ์ ์๋ค.
sum(0)
.then((result) => {
console.log(`๊ฒฐ๊ณผ : ${result}`);
return sum(result); // ๐๐ป promise ๋ฐํํ๋ ํจ์
})
.then((result2) => {
console.log(`๊ฒฐ๊ณผ : ${result2}`);
return sum(result2);
})
.then((result3) => {
console.log(`๊ฒฐ๊ณผ : ${result3}`);
return sum(result3);
})
.then((result4) => {
console.log(`๊ฒฐ๊ณผ : ${result4}`);
return sum(result4);
})
.catch((err) => {
console.log(`๊ฒฐ๊ณผ : ${err}`);
});
Promise์ ์ ์ ๋ฉ์๋
์ฌ๋ฌ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ
๋ณ๋ ฌ์
์ผ๋ก ์ฒ๋ฆฌํ ๋ ์ฌ์ฉํ๋ค.๊ฐ๊ฐ์ ๋น๋๊ธฐ ํธ์ถ ์์๊ฐ ์๊ด ์์ ๋ ์ฌ์ฉํ๋ค.
์ฃผ์ด์ง ํ๋ก๋ฏธ์ค ์ค ํ๋๊ฐ ๊ฑฐ๋ถํ๋ ๊ฒฝ์ฐ, ์ ์ฒด๋ฅผ reject ์ฒ๋ฆฌํ๋ค.
function getEmoticon(icon) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof icon === 'string') {
resolve(icon);
} else {
reject('์ด๋ชจํฐ์ฝ์ ๋ฃ์ด์ฃผ์ธ์!');
}
}, 2000);
});
return promise;
}
Promise.all([getEmoticon('๐'), getEmoticon('๐'), getEmoticon('๐')]).then(
(results) => {
console.log(results); // [ '๐', '๐', '๐' ]
}
);
์ฌ๋ฌ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ค ๊ฐ์ฅ ๋จผ์
fulfilled
๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉ
function getEmoticon(icon, ms) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof icon === 'string') {
resolve(icon);
} else {
reject('์ด๋ชจํฐ์ฝ์ ๋ฃ์ด์ฃผ์ธ์!');
}
}, ms);
});
return promise;
}
Promise.race([
getEmoticon('๐', 4000),
getEmoticon('๐', 2000),
getEmoticon('๐', 1000),
]).then((results) => {
console.log(results); // ๐ ๋ง ๋ฐํ๋จ.
});
์ฌ๋ฌ๊ฐ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋ชจ๋
fulfilled
๋reject
๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ resolveํ๋ promise๋ฅผ ๋ฐํ
function getEmoticon(icon, ms) {
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof icon === 'string') {
resolve(icon);
} else {
reject('์ด๋ชจํฐ์ฝ์ ๋ฃ์ด์ฃผ์ธ์!');
}
}, ms);
});
return promise;
}
Promise.allSettled([
getEmoticon('๐', 4000),
getEmoticon(2, 2000),
getEmoticon('๐', 1000),
]).then((results) => {
console.log(results);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
/**
[
{ status: 'fulfilled', value: '๐' },
{ status: 'rejected', reason: '์ด๋ชจํฐ์ฝ์ ๋ฃ์ด์ฃผ์ธ์!' },
{ status: 'fulfilled', value: '๐' }
]
*/
async/await
Promise๋ฅผ ์กฐ๊ธ ๋ ๊ฐํธํ๊ณ , ๊ฐ๋ ์ฑ ์ข๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด ๋์จ ๋ฌธ๋ฒ
โ async/await๋ promise ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ค. promise์ then,catch,finally ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์ ์ฝ๋ฐฑํจ์๋ฅผ ์ ๋ฌํด์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ ํ์ ์์ด ๋ง์น ๋๊ธฐ์ฒ๋ผ ํ๋ก๋ฏธ์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๊ธฐ๋ณธ๋ฌธ๋ฒ
ํจ์ ์์
async
๋ฅผ ๋ถ์ด๋ฉด๋น๋๊ธฐ์ ์ธ ํจ์์ด๊ณ , Promise๋ฅผ ๋ฐํํ๋ค
๋ผ๊ณ ์ ์ธํ๊ณ , ๋ฐํ ๊ฐ์ด Promise ์์ฑํจ์๊ฐ ์๋์ด๋ ๋ฐํ๋๋ ๊ฐ์ Promise ๊ฐ์ฒด์ ๋ฃ๋๋ค.
const getData = async (url) => {
const response = await fetch(url); // ๐๐ป Promise์ ์ํ ๋ณ๊ฒฝ์ด ๋๊ธฐ์ ๊น์ง ๋ค์์ฝ๋๋ ์คํ๋์ง ์๋๋ค.
const result = await response.json();
console.log(result);
};
await
์async
ํจ์ ์์์๋ง ์ฌ์ฉํ ์ ์๊ณ , Promise๋ฅผ ๋ฐํํ๋ ํจ์ ์์await
๋ฅผ ๋ถ์ด๋ฉด Promise๊ฐ ์ฑ๊ณต ์ํ ๋๋ ์คํจ ์ํ๋ก ๋ฐ๋๊ธฐ ์ ๊น์ง๋ ๋ค์ ์ฐ์ฐ์ ํ์ง์์ ๋๊ธฐ์ ์ผ๋ก ์๋๋๋ค.
async/await ์์ธ์ฒ๋ฆฌ
Promise๋ ํ์ ์ฒ๋ฆฌ๊ฐ ๋ง์์ง์๋ก then ๋ด๋ถ์ ์ฝ๋๊ฐ ์ค์ฒฉ๋๋ฉด์ ์ฝ๋ ํ๋ฆ์ด ๋ณต์กํด์ง๋ ์ํฉ์ ๋ณด์ํ๊ธฐ ์ํด
try/catch
์ผ๋ก ๊ฐ๋จํ ์ฒ๋ฆฌ ํ ์ ์๋ค.
const getData = async (url) => {
try {
const response = await fetch(url);
const result = await response.json();
console.log(result);
} catch (error) {
console.log(error);
}
};
๐ ์ฐธ๊ณ
Last updated