[JS] ์๋ฐ์คํฌ๋ฆฝํธ RORO ๋์์ธ ํจํด / ์คํ ํธ๋ ์ด์ค / ์๋ฌ ์ ํ
TL;DR
RORO ํจํด์ Receive an Object, Return and Object์ ์ฝ์๋ค. ํจ์์ ํ๋ผ๋ฏธํฐ์ ๋ฆฌํด๊ฐ ๋ชจ๋ ๊ฐ์ฒด์ธ๊ฑธ ๋งํ๋ค. ES6๋ถํฐ ์ง์ํ๋ ๊ตฌ์กฐ๋ถํดํ ๋น ๋๋ถ์ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ RORO ํจํด์ ์ฌ์ฉํ ์ ์๋ค. ํ๋ผ๋ฏธํฐ ์ ์ ๋ฐฉ์(RORO ํจํด)๋ง ์ด์ง ๋ฐ๊ฟจ์ง๋ง ๊ฐ๋ ์ฑ์ ๋งค์ฐ ์ข์์ง๋ค. RORO ํจํด์ ์ฅ์ ์ ์๋์ ๊ฐ๋ค.
- ์ด๋ฆ์ด ์ง์ ๋ ํ๋ผ๋ฏธํฐ (Named parameters)
- ๋ช ์์ ์ธ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ณธ๊ฐ (Cleaner default parameters)
- ๋ ๋ง์ ์ ๋ณด ๋ฐํ (Richer return values)
- ํจ์ ํฉ์ฑ ์ฉ์ด (Easy function composition)
์ด๋ฆ์ด ์ง์ ๋ ํ๋ผ๋ฏธํฐ
ํ๋ผ๋ฏธํฐ์ {}
์ค๊ดํธ๋ง ์ถ๊ฐํด์ฃผ๋ฉด ๊ฐ๋จํ๊ฒ RORO ํจํด์ ์ ์ฉํ ์ ์๋ค. ํ๋ผ๋ฏธํฐ๊ฐ ๊ฐ์ฒด ํํ์ด๋ฏ๋ก ํจ์ ํธ์ถ ์ ํ๋ผ๋ฏธํฐ ์์๋ฅผ ์ ๊ฒฝ์ฐ์ง ์์๋ ๋๋ค.
// RORO ํจํด ์ฌ์ฉ ์
const getSquare = function (xPosition, yPosition, width, height) {
/*...*/
};
// RORO ํจํด ์ฌ์ฉ ํ
const getSquare = function ({ xPosition, yPosition, width, height }) {
/*...*/
};
// ํจ์ ํธ์ถ
getSquare({ xPosition: 60, yPosition: 80, width: 88, height: 188 });
์๋์ฒ๋ผ ๊ตฌ์กฐ๋ถํดํ ๋น ๊ธฐ๋ฅ์ ์ด์ฉํด ์ํ๋ ์ด๋ฆ์ ์ง์ ํด์ ์ฌ์ฉํ ์ ์๋ค.
const getSquare = function ({
xPosition: x,
yPosition: y,
width: w,
height: h,
}) {
/*...*/
};
// getSquare ํจ์์ ํ๋ผ๋ฏธํฐ๋ฅผ (์ผ์ชฝ๋ถํฐ) x, y, w, h ๋ณ์๋ช
์ผ๋ก ์ฌ์ฉ
๋ช ์์ ์ธ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ณธ๊ฐ
์๋์ฒ๋ผ ํ๋ผ๋ฏธํฐ๊ฐ ๋น์ด์๋ ์ํ๋ก ํธ์ถํ๋ฉด Cannot desctructure ...
์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ๊ตฌ์กฐ๋ถํด๋ฅผ ์คํํ ๋์(ํ๋ผ๋ฏธํฐ)๊ฐ undefined
์ด๊ธฐ ๋๋ฌธ์ด๋ค.
getSquare(); // Cannot desctructure ...
์ด๋ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ณธ๊ฐ์ผ๋ก {}
๋น ๊ฐ์ฒด๋ฅผ ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
const getSquare = function ({
xPosition: x,
yPosition: y,
width: w,
height: h,
} = {}) {
/* ... */
};
ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌ๋ฐ์ง ์์์ ๋์ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ ์๋ ์๋ค.
const getSquare = function ({
xPosition: x = 100, // xPosition(x)์ ๊ธฐ๋ณธ๊ฐ์ 100์ผ๋ก ์ค์
yPosition: y = 200, // yPosition(y)์ ๊ธฐ๋ณธ๊ฐ์ 200์ผ๋ก ์ค์
width: w,
height: h,
} = {}) {
/* ... */
};
๋ ๋ง์ ์ ๋ณด ๋ฐํ
์๋ฐ์คํฌ๋ฆฝํธ์์ ํจ์๋ ํ ๊ฐ์ง ๊ฐ๋ง ๋ฐํํ ์ ์๋ค. ํ์ง๋ง ๋ฐํ๊ฐ์ด ๊ฐ์ฒด๋ผ๋ฉด ๊ตฌ์กฐ๋ถํดํ ๋น์ ํตํด ์ํ๋ ์์ฑ๋ง ๋ณ์๋ก ๋ฐ์์ฌ ์ ์๋ค. ์ฆ RORO ํจํด์ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉด ๋ ๋ง์ ์ ๋ณด์ ์ ๊ทผํ ์ ์๋ ๊ฒ.
const { position, size } = getSquare({
/* ... */
});
๐๏ธ ์ฐธ๊ณ ๋ก ์ ๋๋ ์ดํฐ ํจ์๋ ์ฌ๋ฌ ๊ฐ์ ์์ฐจ์ ์ผ๋ก ๋ฐํํ ์ ์๋ค.
ํจ์ ํฉ์ฑ
2๊ฐ ์ด์์ ํจ์๋ฅผ ํฉ์ณ์ ๋ง๋ ํจ์๋ฅผ ํฉ์ฑ ํจ์๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์๋ ์์ ์์ pipe
ํจ์๋ ์ฌ๋ฌ ํจ์๋ค์ ์ธ์๋ก ๋ฐ์ ํ reduce
๋ฉ์๋๋ฅผ ํตํด ๊ฐ ํจ์๋ค์ ์คํํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
function pipe(...fns) {
// fns -> [fn1, fn2, fn3, ...]
return (param) =>
fns.reduce(
(result, fn) => fn(result), // ์ด์ ํจ์์ ์คํ ๊ฒฐ๊ณผ(result)๊ฐ ํ์ฌ ํจ์์ ํ๋ผ๋ฏธํฐ์ ๋ค์ด๊ฐ
param,
);
}
์๋ ๊ฐ์ ํฉ์ฑ ํจ์๋ฅผ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ณธ๋ค. saveUser
ํจ์์ ๋๊ธด userInfo
๊ฐ์ pipe
ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธด ๊ฐ ํจ์๋ฅผ ์ฐจ๋ก๋๋ก(validate ~) ๊ฑฐ์น๊ฒ ๋๋ค.
const saveUser = pipe(validate, normalize, persist);
saveUser(userInfo);
ํฉ์ฑ ํจ์๋ฅผ ๋ง๋ค์ง ์์๋ค๋ฉด ์๋์ฒ๋ผ ์คํ๋๋ค.
persist(normalize(validate(userInfo)));
๋ง์ฝ ๋ชจ๋ ํจ์๊ฐ RORO ํจํด์ ์ ์ฉํด ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ๋ฐ๊ณ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค๋ฉด, ๊ฐ ํจ์๋ ์ธ์์์ ํ์ํ ๊ฐ๋ง ์ฌ์ฉํ๊ณ , ๋๋จธ์ง ๊ฐ์ ...rest
ํจํด์ผ๋ก ๊ทธ๋๋ก ๋ฐํํ ์ ์๋ค.
function normalize({ email, username, ...rest }) {
// normalize ๋ก์ง(email๊ณผ username๋ง ์ฌ์ฉ)
return {
email, // normalized email(email ์ธ์์ normalize ๋ก์ง์ ์ํํ ๊ฒฐ๊ณผ)
username, // normalized username(username ์ธ์์ normalized ๋ก์ง์ ์ํํ ๊ฒฐ๊ณผ)
...rest, // ์ฌ์ฉํ์ง ์๋ ์ธ์๋ ๊ทธ๋๋ก ๋ฐํ
};
}
function validate({
id,
firstName,
lastName,
email = requiredParam(), // ํ์
username = requiredParam(), // ํ์
pass = requiredParam(), // ํ์
address,
...rest
}) {
// ์ ํจ์ฑ ๊ฒ์ฌ ๋ก์ง
return {
id,
firstName,
lastName,
email,
username,
pass,
address,
...rest, // ์ฌ์ฉํ์ง ์์ ํ๋ผ๋ฏธํฐ
};
}
function normalize({ email, username, ...rest }) {
// email, username์ ๋ํ normalize ๋ก์ง
return {
email,
username,
...rest, // ์ฌ์ฉํ์ง ์์ ํ๋ผ๋ฏธํฐ
};
}
async function persist({
upsert = true, // update and insert
...info
}) {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค์ userInfo ์ ์ฅ
return {
operation,
status, // ์ฒ๋ฆฌ ์ํ
saved: info,
};
}
function pipe(...fns) {
return (param) => fns.reduce((result, fn) => fn(result), param);
}
const saveUser = pipe(validate, normalize, persist);
saveUser(userInfo);
ํ์ ์ธ์
์๋ ์ฝ๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ณด๋ฉด requiredParam()
ํจ์์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉํ๋ค. ์ด์ฒ๋ผ ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ๊ฐ์ ๋ฆฌํฐ๋ด ๋ฟ๋ง ์๋๋ผ ํจ์ ์คํ ๊ฒฐ๊ณผ๋ ์ฌ์ฉํ ์ ์๋ค.
function validate({
id,
firstName,
lastName,
email = requiredParam(),
username = requiredParam(),
pass = requiredParam(),
address,
...rest
}) {
return {
/*...*/
};
}
ํจ์์ ํ์ํ ํ๋ผ๋ฏธํฐ๊ฐ ์ ๋ฌ๋๋ค๋ฉด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ง์ ํด๋ requiredParam()
ํจ์๋ ์คํ๋์ง ์๋๋ค. ์ด๋ฐ ํน์ฑ์ ์ด์ฉํด requiredParam()
ํจ์๋ฅผ ์คํํ๋ค๋ฉด ํญ์ ์๋ฌ๋ฅผ ๋ฐ์ํ๋๋ก ํด์, ํ์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์ง ์์์ ๋ ์๋ฌ๋ฅผ ํ์ํ ์ ์๋ค.
function requiredParam(param) {
const requiredParamError = new Error(
`Required parameter, "${param}" is missing.`,
);
// preserve original stack trace
// Error.captureStackTrace๋ V8 ์์ง์์๋ง ์ฌ์ฉํ ์ ์๋ ๋นํ์ค์ด๋ฏ๋ก ์๋์ฒ๋ผ ์กฐ๊ฑด ์ถ๊ฐ
if (Error.captureStackTrace) {
Error.captureStackTrace(requiredParamError, requiredParam);
// requiredParam ํจ์๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ๋ฐ์ํ ํธ์ถ๋ง ํ์
}
throw requiredParamError;
}
์๋์ฒ๋ผ ์ฌ์ฉํ๋ค.
function validate({
// ... ์๋ต
email = requiredParam('email'),
} = {}) {
/*...*/
}
// validate ํจ์ ํธ์ถ ์ ํ์ ํ๋ผ๋ฏธํฐ์ธ email์ ๋๋ฝํ๋ค๋ฉด ์๋ ์ค๋ฅ ์ถ๋ ฅ
// Uncaught Error: Required parameter, "email" is missing.
๋ฒ์ธ — ์คํ ํธ๋ ์ด์ค(Stack Trace)
throw
๋ฌธ์ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ํจ์ ์คํ์ด ์ค์ง๋๊ณ (throw
์ดํ์ ์ฝ๋๋ ์คํํ์ง ์์) ์ ์ดํ๋ฆ์ ์ฝ์คํ์ ์ฒซ๋ฒ์งธcatch
๋ธ๋ก์ผ๋ก ์ ๋ฌ๋๋ค.catch(e)
์ธ์๋ ์ ํ์ ์ด๋ค.- ์๋ฌ(error) ๊ฐ์ฒด๋ ์๋ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋ค
name
: ์๋ฌ ์ด๋ฆmessage
: ์๋ฌ ์์ธ ๋ด์ฉstack
(๋นํ์ค ํ๋กํผํฐ) : ์๋ฌ ๋ฐ์ ์์ธ์ด ์ด๋ค ํ์ผ ๋๋ฌธ์ธ์ง์ ๋ํ ๊ธฐ๋ก(์ฝ์คํ).
console.trace()
๐ก ์คํ ํธ๋ ์ด์ค๋ ์ → ์๋ ์์ผ๋ก ์ฝ๋๋ค.
console.trace()
๋ฉ์๋๊ฐ ์คํ๋ ์์ ์ ์คํ ํธ๋ ์ด์ค๋ฅผ ์ฝ์์ ์ถ๋ ฅํ๋ค. ์๋ ์์์์ c
ํจ์๋ฅผ ์คํํ๊ณ ์คํ์์ ์ ๊ฑฐ ๋์ผ๋ฏ๋ก console.trace()
๋ฅผ ์คํํ๋ฉด b
, a
๋ง ์ถ๋ ฅํ๋ค.
function c() {
console.log('c');
}
function b() {
console.log('b');
c();
console.trace();
}
function a() {
console.log('a');
b();
}
a();
// b @VM3226:8 - console.trace ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// a @VM3226:13 - b ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// (์ต๋ช
) @VM3226:16 - a ํจ์๋ฅผ ํธ์ถํ ๊ณณ
Error.captureStackTrace()
๊ฐ๋ ์ดํด
๐ก ์๋ฌ๋ ํธ์ถ์(caller) ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค. ์ฆ, ์ฝ์คํ์ ์๋ ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค.
Error.captureStackTrace
ํจ์๋ ํ์ฌ ์คํ ํธ๋ ์ด์ค๋ฅผ ์บก์ฒํ๊ณ ๋์ ๊ฐ์ฒด(์ฒซ๋ฒ์งธ ์ธ์) ์์ stack
ํ๋กํผํฐ๋ฅผ ๋ง๋ค์ด ์ ์ฅํ๋ค. ์ฒซ๋ฒ์งธ ์ธ์๋ ๊ฐ์ฒด, (์ ํ)๋๋ฒ์งธ ์ธ์๋ ํจ์๋ฅผ ๋ฐ๋๋ค.
๋๋ฒ์งธ ์ธ์์ ์๋ฌด๊ฒ๋ ๋ช ์ํ์ง ์์ผ๋ฉด ํ์ฌ ์คํ ํธ๋ ์ด์ค๋ฅผ ๋ชจ๋ ์บก์ฒํ๋ค. ๋๋ฒ์งธ ์ธ์์ ํจ์๋ฅผ ๋ช ์ํ๋ฉด, ํด๋น ํจ์๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ๋ฐ์ํ ํธ์ถ๋ง ํ์ํ๋ค(ํด๋น ํจ์์ ๊ทธ ๋ค์ ์์ธ ํธ์ถ ์คํ์ ๋ชจ๋ ์จ๊ธด๋ค).
์์) ๋๋ฒ์งธ ์ธ์๋ฅผ ๋ช ์ํ์ง ์์์ ๋
์๋ ์์์์ a
ํจ์ ํธ์ถ → b
ํจ์ ํธ์ถ ํ a
, b
๊ฐ ์คํ์ ์์ธ๋ค. b
ํจ์ ๋ณธ๋ฌธ์์ c
ํจ์๋ฅผ ์คํํ๊ธฐ ์ ์ Error.captureStackTrace
ํจ์๋ฅผ ์คํํ๊ธฐ ๋๋ฌธ์, ํด๋น ์์ ์ ์คํ ํธ๋ ์ด์ค๋ฅผ ์บก์ฒํ์ฌ b
, a
๋ฅผ ์ถ๋ ฅํ๋ค.
const myObj = {};
function c() {}
function b() {
// Here we will store the current stack trace into myObj
Error.captureStackTrace(myObj);
c();
}
function a() {
b();
}
// First we will call these functions
a();
// Now let's see what is the stack trace stored into myObj.stack
console.log(myObj.stack);
// at b (<anonymous>:7:9) - Error.captureStackTrace ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at a (<anonymous>:12:3) - b ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at <anonymous>:16:1 - a ํจ์๋ฅผ ํธ์ถํ ๊ณณ
์์) ๋๋ฒ์งธ ์ธ์๋ฅผ ๋ช ์ํ์ ๋
์๋ ์์์์ ์คํ์ a
→ b
→ c
→ d
์์ผ๋ก ์์ธ๋ค. ํ์ง๋ง Error.captureStackTrace
์ ํจ์ b
๋ฅผ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ b
์ b
์์ ์์ธ ํ๋ ์(c
, d
)๋ค์ ๋ชจ๋ ์จ๊ธด๋ค. ๋ฐ๋ผ์ ์ฝ์์ ์ฐํ๋ ์คํ ํธ๋ ์ด์ค๋ a
๋ง ๋์จ๋ค.
const myObj = {};
function d() {
// Here we will store the current stack trace into myObj
// This time we will hide all the frames after `b` and `b` itself
Error.captureStackTrace(myObj, b);
}
function c() {
d();
}
function b() {
c();
}
function a() {
b();
}
// First we will call these functions
a();
// Now let's see what is the stack trace stored into myObj.stack
console.log(myObj.stack);
// at a (<anonymous>:18:3) - b ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at <anonymous>:22:1 - a ํจ์๋ฅผ ํธ์ถํ ๊ณณ
์์) ํ์ ์ธ์ ๊ตฌ๋ถ ํจ์์ ์ ์ฉ
์๋ ์ฝ๋์ requiredParam
ํจ์๋ RORO ํจํด์์ ํ์ ์ธ์๋ฅผ ๋ฐ์ง ์์์ ๋ ์๋ฌ๋ฅผ ์ถ๋ ฅํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํจ์๋ค. func
ํจ์๋ฅผ ์คํํ๋ฉด ํธ์ถ ์คํ์ func
→ requiredParam
์์ผ๋ก ์์ธ๋ค.
Error.captureStackTrace
๋๋ฒ์งธ ์ธ์์ ๋ช
์ํ ํจ์๊ฐ requiredParam
์ด๋ฏ๋ก requiredParam
ํจ์์ ๊ทธ ์ดํ์ ์์ธ ํ๋ ์(ํธ์ถ ์คํ)์ ๋ชจ๋ ์จ๊ธด๋ค. ๋ฐ๋ผ์ ์คํ ํธ๋ ์ด์ค๋ func
๋ง ํ์ํ๋ค.
๐ก Uncaught Error๋ ์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ์ ๋(์๋ฌ๋ฅผ ํธ๋ค๋งํ๋ ๊ณณ์ด ์์ ๋) ๋ฐ์ํ๋ค
function requiredParam(param) {
const requiredParamError = new Error(
`Required parameter, "${param}" is missing.`,
);
// preserve original stack trace
// Error.captureStackTrace๋ V8 ์์ง์์๋ง ์ฌ์ฉํ ์ ์๋ ๋นํ์ค์ด๋ฏ๋ก ์๋์ฒ๋ผ ์กฐ๊ฑด ์ถ๊ฐ
if (Error.captureStackTrace) {
Error.captureStackTrace(requiredParamError, requiredParam);
// requiredParam ํจ์๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ๋ฐ์ํ ํธ์ถ๋ง ํ์
}
throw requiredParamError;
}
function func({ name = requiredParam('name'), age } = {}) {
return { name, age };
}
func({ age: 30 });
// Uncaught Error: Required parameter, "name" is missing.
// at func (<anonymous>:13:24) - requiredParam ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at <anonymous>:17:1 - func ํจ์๋ฅผ ํธ์ถํ ๊ณณ
Error.captureStackTrace
๋๋ฒ์งธ ์ธ์์ ์๋ฌด๊ฒ๋ ๋ช
์ํ์ง ์์ผ๋ฉด ์คํ ํธ๋ ์ด์ค๋ฅผ ๋ชจ๋ ์ถ๋ ฅํ๋ค.
func({ age: 30 });
// Uncaught Error: Required parameter, "name" is missing.
// at requiredParam (<anonymous>:7:11) - captureStackTrace ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at func (<anonymous>:13:24) - requiredParam ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at <anonymous>:17:1 - func ํจ์๋ฅผ ํธ์ถํ ๊ณณ
์๋ฌ ์ ํ์ setTimeout
try/catch ์์
์๋ฌ๋ ํธ์ถ์(caller) ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค(์ฝ ์คํ์ ์๋ ๋ฐฉํฅ; ํ์ฌ ์คํ ์ปจํ
์คํธ ์ง์ ์ ์คํ ์ปจํ
์คํธ ๋ฐฉํฅ). ์๋ ์ฝ๋๋ โbaz
ํจ์ ํธ์ถ → โbar
ํจ์ ํธ์ถ → โfoo
ํจ์ ํธ์ถ → โfoo
ํจ์์์ ์๋ฌ throw
… ์์๋ก ์คํ๋๊ณ , foo
ํจ์์์ ๋ฐ์ํ ์๋ฌ๋ ์ด์ ์คํ ์ปจํ
์คํธ(โ → โ ํธ์ถ์ ๋ฐฉํฅ)๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ค.
const foo = () => {
throw Error('foo์์ ๋ฐ์ํ ์๋ฌ'); // โท
};
const bar = () => {
foo(); // โถ
};
const baz = () => {
bar(); // โต
};
try {
baz(); // โด
} catch (err) {
console.error(err);
}
// at foo (<anonymous>:2:9) - ์๋ฌ๋ฅผ throw ํ ๊ณณ
// at bar (<anonymous>:6:3) - foo ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at baz (<anonymous>:10:3) - bar ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at <anonymous>:14:3 - baz ํจ์๋ฅผ ํธ์ถํ ๊ณณ
foo
ํจ์์์ throw
ํ ์๋ฌ๋ bar
baz
์์ ๋ชจ๋ catchํ์ง ์๊ธฐ ๋๋ฌธ์ ํธ์ถ์๊น์ง ์ ํ๋ ํ ์ ์ญ์์ ์บ์น๋๋ค. ๋ง์ฝ throw
ํ ์๋ฌ๋ฅผ ์ด๋์์๋ catchํ์ง ์์๋ค๋ฉด ํ๋ก๊ทธ๋จ์ ๊ฐ์ ์ข
๋ฃ๋๋ค.
๋น๋๊ธฐ ํจ์์ธ setTimeout
๊ณผ ํ๋ก๋ฏธ์ค ํ์ ์ฒ๋ฆฌ ๋ฉ์๋(then
๋ฑ)์ ์ฝ๋ฐฑ ํจ์๋ ํธ์ถ์๊ฐ ์๋ค. ์ด ๋์ ํ์คํฌ ํ(๋งคํฌ๋กํ์คํฌํ/๋ง์ดํฌ๋กํ์คํฌํ)์ ๋ค์ด๊ฐ์ ์ฝ์คํ์ด ๋น์ด์์ ๋๊น์ง ๋๊ธฐํ๋ค. ์ฝ์คํ์ด ๋น์๋ค๋ฉด ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ฝ์คํ์ผ๋ก ํธ์๋ ํ ์คํ๋๋ค. ์ด๋ ์ฝ๋ฐฑ ํจ์์ ์คํ ์ปจํ
์คํธ๋ ์ฝ์คํ์ ๊ฐ์ฅ ํ๋จ์ ์์นํ๊ฒ ๋๋ค(์ฝ์คํ์ด ๋น์ด์ง ํ ํธ์๋์ผ๋ฏ๋ก). ์ฆ ์๋ฌ๋ฅผ ์ ํํ ํธ์ถ์๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒ์ด๋ค.
try {
setTimeout(() => {
throw new Error('์๋ฌ ๋ฐ์');
}, 1000);
} catch (e) {
console.error('์๋ฌ ์บ์น', e);
}
// Uncaught Error: ์๋ฌ ๋ฐ์ (์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ์ผ๋ฏ๋ก Uncaught ์๋ฌ ๋ฐ์)
๐ก ์๋ฌ๋ ํธ์ถ์ ๋ฐฉํฅ์ผ๋ก ์ ํ๋์ง๋ง `setTimeout`์ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ ๊ฒ์ `setTimeout` ํจ์๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ์ฝ๋ฐฑ ํจ์๊ฐ ๋ฐ์ ์ํจ ์๋ฌ๋ `catch` ๋ธ๋ก์์ ์บ์น๋์ง ์๋๋ค. `setTimeout` ํจ์๊ฐ ์ฝ๋ฐฑ ํจ์์ ํธ์ถ์๊ฐ ๋๊ธฐ ์ํด์ ์ฝ๋ฐฑ ํจ์์ ์คํ ์ปจํ ์คํธ ์ด์ ์ `setTimeout` ์คํ ์ปจํ ์คํธ๊ฐ ์์ด์ผ ํ๋ค. ํ์ง๋ง `setTimeout`์ ๋น๋๊ธฐ ํจ์์ด๋ฏ๋ก ์คํ ์ฆ์ ์ข ๋ฃ๋ผ์ ์ฝ์คํ์์ ์ ๊ฑฐ๋๋ค.
setTimeout
ํจ์ ํธ์ถ →setTimeout
ํจ์์ ์คํ ์ปจํ ์คํธ ์์ฑ → ์ฝ์คํ์ ํธ์๋ ํ ์คํsetTimeout
์ ๋น๋๊ธฐ ํจ์์ด๋ฏ๋ก ์ฝ๋ฐฑ ํจ์ ํธ์ถ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ฆ์ ์ข ๋ฃ → ์ฝ์คํ์์ ์ ๊ฑฐ- ํ์ด๋จธ(1์ด) ๋ง๋ฃ →
setTimeout
์ ์ฝ๋ฐฑ ํจ์๋ ํ์คํฌ ํ๋ก ๋ค์ด๊ฐ ํ ์ฝ์คํ์ด ๋น์ด์์ ๋๊น์ง ๋๊ธฐ - ์ฝ์คํ์ด ๋น์๋ค๋ฉด ์ด๋ฒคํธ ๋ฃจํ์ ์ํด ์ฝ์คํ์ผ๋ก ํธ์
- ์ฝ๋ฐฑ ํจ์ ์คํ → ์๋ฌ
throw
→ ํธ์ถ์๊ฐ ์์ผ๋ฏ๋ก catch ๋ธ๋ก์์ ์๋ฌ ์บ์น ๋ชปํจ
Promise ์์
ํ๋ก๋ฏธ์ค์ ์ฝ๋ฐฑ ํจ์์ ํ์ ์ฒ๋ฆฌ ๋ฉ์๋ ๋ด๋ถ์ try/catch๊ฐ ์๋ฌต์ ์ผ๋ก ๊ฐ์ธ๊ณ ์๋ค. reject
๋ฅผ ํธ์ถํ๊ฑฐ๋ ์๋ฌ๋ฅผ throw
ํ๋ฉด .catch
ํ์ ์ฒ๋ฆฌ ๋ฉ์๋์์ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
new Promise((resolve, reject) => {
throw new Error('์๋ฌ ๋ฐ์');
}).catch((e) => console.error('์๋ฌ ์บ์น', e));
// ์๋ฌ ์บ์น ์ฑ๊ณต. reject๋ฅผ ํธ์ถํ์ง ์๊ณ ๋ .catch ๋ฉ์๋์์ ์๋ฌ๋ฅผ ์บ์นํ ์ ์๋ค
// at <anonymous>:2:9 - ์๋ฌ๋ฅผ throwํ ๊ณณ
// at new Promise (<anonymous>) - Promise์ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ ๊ณณ
// at <anonymous>:1:1 - Promise ์์ฑ์๋ฅผ ํธ์ถํ ๊ณณ
ํ์ง๋ง ์๋ ์ฝ๋๋ ํ๋ก๋ฏธ์ค๊ฐ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค. ์์ ๋ง์ฐฌ๊ฐ์ง๋ก setTimeout
์ ์ฝ๋ฐฑ ํจ์๊ฐ ์ฝ์คํ์ ๋ค์ด๊ฐ ์์ ์ ํธ์ถ์๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค(์ฝ๋ฐฑ ํจ์์ ์คํ ์ปจํ
์คํธ๊ฐ ์ฝ์คํ์ ๊ฐ์ฅ ํ๋จ์ ์์น).
new Promise((resolve, reject) => {
setTimeout(() => {
throw new Error('์๋ฌ ๋ฐ์');
}, 1000);
}).catch((e) => console.error('์๋ฌ ์บ์น', e));
// Uncaught Error: ์๋ฌ ๋ฐ์ (์๋ฌ๋ฅผ ์บ์นํ์ง ๋ชปํ์ผ๋ฏ๋ก Uncaught ์๋ฌ ๋ฐ์)
// setTimeout์ ํ์ด๋จธ๋ฅผ 0์ผ๋ก ์ค์ ํด๋ ๊ฒฐ๊ณผ๋ ๋์ผํ๋ค
ํ๋ก๋ฏธ์ค ์ฝ๋ฐฑ ํจ์์ 2๋ฒ์งธ ์ธ์์ธ reject
๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค. ์๋ฌ๋ ํธ์ถ์ ๋ฐฉํฅ์ผ๋ก ์ ํ๋๋ฏ๋ก reject
ํจ์์ ์คํ ์ปจํ
์คํธ๊น์ง ์ ํ๋ ํ catch
๋ธ๋ก์ผ๋ก ๋์ด๊ฐ๋ค.
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('์๋ฌ ๋ฐ์'));
}, 1000);
}).catch((e) => console.error('์๋ฌ ์บ์น', e));
// ์๋ฌ ์บ์น ์ฑ๊ณต
// at <anonymous>:3:12 - reject ํจ์๋ฅผ ํธ์ถํ ๊ณณ
๋ ํผ๋ฐ์ค
- tinyblog
- ์๋ฐ์คํฌ๋ฆฝํธ ๋์์ธ ํจํด: RORO
- ์๋ฐ์คํฌ๋ฆฝํธ ์๋ฌ์ ์คํ ํธ๋ ์ด์ค ์ฌํ
- Elegant patterns in modern JavaScript: RORO
- ํ๋ผ๋ฏธ์ค์ ์๋ฌ ํธ๋ค๋ง
- Promise | PoiemaWeb
๊ธ ์์ ์ฌํญ์ ๋ ธ์ ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[HTML/CSS] ์์๋๋ฉด ์ ์ฉํ CSS ์ต์ ๊ธฐ๋ฅ 6๊ฐ์ง (0) | 2024.05.01 |
---|---|
[CS] RISC / CISC ์ํคํ ์ฒ ์ฐจ์ด์ (0) | 2024.05.01 |
[React] ๋ฆฌ์กํธ ๋ผ์ฐํฐ React Router v6 ๋ฐ๋์ ํบ์๋ณด๊ธฐ (0) | 2024.04.30 |
[Algorithm] ํ๋ก๊ทธ๋๋จธ์ค ๋น๋ฐ์ง๋ ๋ฌธ์ ํ์ด (0) | 2024.04.30 |
[AWS] EC2 ๋์คํฌ ๊ณต๊ฐ ๋๋ฆฌ๊ธฐ / ์ฌ์ ๊ณต๊ฐ ํ๋ณดํ๊ธฐ (0) | 2024.04.30 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[HTML/CSS] ์์๋๋ฉด ์ ์ฉํ CSS ์ต์ ๊ธฐ๋ฅ 6๊ฐ์ง
[HTML/CSS] ์์๋๋ฉด ์ ์ฉํ CSS ์ต์ ๊ธฐ๋ฅ 6๊ฐ์ง
2024.05.01 -
[CS] RISC / CISC ์ํคํ ์ฒ ์ฐจ์ด์
[CS] RISC / CISC ์ํคํ ์ฒ ์ฐจ์ด์
2024.05.01 -
[React] ๋ฆฌ์กํธ ๋ผ์ฐํฐ React Router v6 ๋ฐ๋์ ํบ์๋ณด๊ธฐ
[React] ๋ฆฌ์กํธ ๋ผ์ฐํฐ React Router v6 ๋ฐ๋์ ํบ์๋ณด๊ธฐ
2024.04.30 -
[Algorithm] ํ๋ก๊ทธ๋๋จธ์ค ๋น๋ฐ์ง๋ ๋ฌธ์ ํ์ด
[Algorithm] ํ๋ก๊ทธ๋๋จธ์ค ๋น๋ฐ์ง๋ ๋ฌธ์ ํ์ด
2024.04.30