모던 리액트 Deep Dive를 읽다가 발견한 오류에 대해서 써보고자 한다.
책에서 발견한 오류는 아래와 같다.
function bar() {
return console.log("bar");
}
function baz() {
console.log("baz");
}
function foo() {
console.log("foo");
setTimeout(bar(), 0);
baz();
}
foo();
위 코드를 브라우저 환경과 Node.js 환경에서 각각 실행시켜보겠다.
브라우저 환경
foo
bar
node:internal/errors:541
throw error;
^
TypeError [ERR_INVALID_ARG_TYPE]: The "callback" argument must be of type function. Received undefined
at setTimeout (node:timers:143:3)
at foo (/Users/gwangsoo/Desktop/modern-react-deep-dive/index.js:11:3)
at Object.<anonymous> (/Users/gwangsoo/Desktop/modern-react-deep-dive/index.js:15:1)
at Module._compile (node:internal/modules/cjs/loader:1368:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1426:10)
at Module.load (node:internal/modules/cjs/loader:1205:32)
at Module._load (node:internal/modules/cjs/loader:1021:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:142:12)
at node:internal/main/run_main_module:28:49 {
code: 'ERR_INVALID_ARG_TYPE'
}
Node.js 환경
우선 setTimeout의 인자를 보겠다.
setTimeout(functionRef)
setTimeout(functionRef, delay)
setTimeout(functionRef, delay, param1, param2, ...)
첫 번째 인자인 functionRef
에 대해서만 알아보겠다. (다른 인자에 대한 내용은 MDN을 참고)
functinoRef
에는 function을 전달해 주어야 한다. 하지만 위 코드의 경우 함수를 실행한 결과 값인 console.log("bar")
를 전달한다. 이는 setTimeout의 매개변수와 맞지 않기 때문에 오류를 발생시켜야 한다.
위에서 브라우저 환경과 Node.js 환경에서 실행 결과가 달랐던 이유는 오류 처리 방식이 다르기 때문이다.
브라우저 환경의 경우 setTimeout 오류를 무시하고 실행하기 때문에 foo bar baz
라는 출력 결과가 나오지만, Node.js 환경의 경우 보다 엄격한 오류 검사를 실행하기 때문에 에러를 반환한다.
그렇다면 위의 코드가 동작하게 하려면 어떻게 수정해야 할까? 내가 생각한 방법은 다음과 같다.
function bar() {
console.log("bar");
}
function foo() {
setTimeout(bar, 0);
}
function bar() {
console.log("bar");
}
function foo() {
setTimeout(() => bar(), 0);
}
이외에도 다양한 방법이 있지만, 가장 먼저 떠오르는 방법을 적어보았다.
setInterval의 경우에도 setTimeout과 같이 브라우저 환경에서는 오류를 반환하지 않고 정상 작동하지만, Node.js 환경에서는 에러를 반환한다.
function sayHi() {
console.log("hi");
}
function hi() {
setInterval(sayHi(), 1000);
}
hi();
브라우저 환경
hi
node:internal/errors:541
throw error;
^
TypeError [ERR_INVALID_ARG_TYPE]: The "callback" argument must be of type function. Received undefined
at setInterval (node:timers:213:3)
at hi (/Users/gwangsoo/Desktop/temp.js:87:3)
at Object.<anonymous> (/Users/gwangsoo/Desktop/temp.js:90:1)
at Module._compile (node:internal/modules/cjs/loader:1368:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1426:10)
at Module.load (node:internal/modules/cjs/loader:1205:32)
at Module._load (node:internal/modules/cjs/loader:1021:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:142:12)
at node:internal/main/run_main_module:28:49 {
code: 'ERR_INVALID_ARG_TYPE'
}
Node.js 환경
위 스크린샷들을 보면 맨 마지막 줄에 undefined
가 출력되는 것을 볼 수 있다. 이는 다음과 같은 이유 때문이다.
const number = 10; // 이 코드를 입력 후 엔터를 누르면 undefined가 출력된다.
function sayHi() {
console.log('hi');
}
sayHi();
당연하게도 함수의 반환값이 없기 때문에 undefined가 출력된다.