이번 노트에서는 여러분이 '비동기 실행'을 제대로 이해했는지 간단히 확인하는 시간을 가져볼게요.
아래 코드를 보세요.
const fs = require('fs');
let test = 1;
fs.readFile('./new', 'utf8', (err, data) => {
test = 2;
});
console.log(test); // Question!
지금 주석에 Question!이라고 표시된 곳에서 출력되는 test 변수의 값은 뭘까요?
답은 1입니다. 왜냐하면 코드의 실행 순서는
const fs = require('fs');
let test = 1; // '첫 번째'
fs.readFile('./new', 'utf8', (err, data) => {
test = 2; // '세 번째'
});
console.log(test); // '두 번째'
이기 때문입니다. readFile 함수가 비동기 실행되는 함수이기 때문에
일단 console.log(test)가 먼저 실행되고,
그 후에야 test 변수에 2가 대입되기 때문입니다.
혹시 왜 이렇게 실행되는지 이해가 안되는 분은 이전 내용을 복습하고 와주세요.
자, 이제 다음 문제입니다. 이 코드를 보세요.
let num = 1;
setTimeout(() => {
num = 2;
}, 1000);
num = 3;
console.log(num);
지금 처음 보는 함수가 등장했죠? 이 코드에 보이는 setTimeout이라는 함수는
setTimeout(callback, milliseconds)
형식의 함수로 milliseconds(밀리세컨즈, 1000분의 1초) 후에 callback 인자에 설정한 함수를 실행합니다.
그러니까
setTimeout(() => {
num = 2;
}, 1000);
이 코드는 1000 밀리세컨즈 초, 그러니까 1초 후에 num 변수에 2를 대입하라는 뜻입니다. setTimeout 함수는 개발자가 직접 비동기 실행을 구현하고 싶을 때 사용할 수 있는 유용한 함수입니다.
그럼 아래 코드의 실행 결과는 무엇일까요.
let num = 1;
setTimeout(() => {
num = 2;
}, 1000);
num = 3;
console.log(num);
답은 3입니다. 왜냐하면 이번에도 작업 순서는 이렇게 되기 때문입니다.
let num = 1; // 첫번째
setTimeout(() => {
num = 2; // 세번째
}, 1000);
num = 3; // 두번째
console.log(num);
지금 코드는
(1) num 변수에 1을 대입
(2) setTimeout 함수 실행(1초 후에 실행될 콜백 설정)
(3) num 변수에 3을 대입
(4) num 변수의 값 출력
(5) setTimeout에서 설정해둔 콜백 실행
이런 순서로 실행됩니다. 비동기 실행이라는 관점에서 보니까 이 코드도 이해하기 별로 어렵지 않죠? 이밖에도 개발자가 비동기 실행을 직접 구현할 수 있게 해주는 함수에는 여러가지가 있습니다. 일단 여러분은 setTimeout 함수만 잘 기억해주세요.