호출 스케줄링(scheduling a call)
은 타이머 함수를 사용해 일정 시간이 경과된 이후에 호출되도록 함수 호출을 예약하는 것을 의미한다.
자바스크립트에서는 타이머 생성 함수로서 setTimeout, setInterval을 제공하며 타이머를 제거할 수 있는 clearTimeout과 clearInterval을 제공한다.
타이머 함수는 ECMAScript 정의 함수는 아니며, 브라우저 및 Node.js 환경에서 제공되는 호스트 객체다.
setTimeout / clearTimeout
setTimeout은 두 번째 인수로 전달받은 시간(delay)으로 단 한번 동작하는 타이머를 생성하며, 타이머 만료 후 첫 번째 인수로 전달받은 콜백 함수를 호출한다.
콜백 함수에 전달해야 하는 인수가 존재하는 경우 세번째 이후 인수로 전달할 수 있다.
delay는 생략시 기본값 0이 지정된다.
// setTimeout 사용 예시
setTimeout(() => console.log(`delay 0`), 1000);
setTimeout((param) => console.log(`this is a ${param}`), 100, "test");
// -> this is a test
setTimeout(() => console.log(`delay 0`));
setTimeout은 타이머를 식별할 수 있는 타이머 id를 반환하며, 반환된 id를 clearTimeout 함수의 인수로 전달하며 취소할 수 있다. 타이머 id는 브라우저에서는 숫자, Node.js에서는 객체이다.
// clearTimeout 사용 예시
const timerId = setTimeout(() => console.log(`timer`), 1500);
console.log(timerId);
clearTimeout(timerId);
setInterval / clearInterval
setInterval은 두 번째 인수로 전달받은 시간(delay)으로 반복 동작하는 타이머를 생성한다.
setTimeout과 유사하지만 setInterval은 타이머가 취소될 때 까지 반복된다는 특징이 있다.
setInterval(() => console.log("3초가 지났습니다."), 3000);
let count = 0;
const timerId2 = setInterval(() => {
count += 1;
if (count >= 5) {
console.log("5초가 지났으므로 반복을 멈춥니다.");
clearInterval(timerId2);
}
}, 1000);
async/await
문법은 ES8(ECMAScript 2017)에 도입된 문법으로, 간단하고 가독성 좋게 비동기 처리를 동기처리처럼 구현할 수 있도록 만들어 준다.
async/await 은 프로미스를 기반으로 동작하며, 프로미스의 후속 처리 메서드를 사용할 필요 없이 동기 처리처럼 프로미스를 사용할 수 있게 된다.
const url = "https://jsonplaceholder.typicode.com/posts/1";
const getPosts = async (url) => {
const res = await fetch(url);
const data = await res.json();
console.log(data);
};
getPosts(url);
async 함수는 async 키워드를 사용해 정의하며, 언제나 프로미스를 반환한다.
async 함수가 명시적으로 프로미스를 반환하지 않더라도 async 함수는 암묵적으로 반환값을 resolve하는 프로미스 반환한다.
/* async 함수 별 선언 방식 */
// 함수 선언문
async function async1(param) {
return param;
}
// 함수 표현식
const async2 = async function (param) {
return param;
};
// 화살표 함수
const async3 = async (param) => {
return param;
};
await 키워드는 프로미스가 settled 상태(fulfilled/rejected)가 될 때까지 대기하다가 settled 상태가 되면 프로미스가 resolve한 처리 결과를 반환한다. await 키워드는 반드시 프로미스 앞에서 사용해야 한다.
async/await는 비동기 함수를 동기적으로 동작하도록 만들어주기 때문에 프로미스가 settled 상태가 될 때까지 대기하면서 다음 실행을 일시 중지 시켰다가 settled가 되면 다시 재개한다. -> 순차적으로 실행
async/await 문법을 사용하는데 있어서 모든 프로미스에 await를 사용할 필요는 없다.
async/await를 사용한다는 것은 순차적으로 동작할 필요가 있는 경우에 한하며, 연관성 없이 개별 수행하는 비동기 처리는 await를 사용할 필요 없다.
코드를 작성하다보면, 에러는 언제든 발생할 수 있다. 그러나 에러에 대한 대처 없이 프로그래밍을 하다보면 에러 때문에 프로그램이 강제종료가 되는 경우가 발생한다.(에러 추적이 어렵다.)
try … catch 문을 사용해 발생한 에러를 처리하도록 작성하면, 프로그램이 강제 종료되지 않은 채 계속 코드를 실행할 수 있다.
try/catch/finally 문은 에러 처리(error handling) 코드를 작성하기 위한 문으로, finally는 생략 가능하다.
• try 코드 블록 안에는 실행될 코드 내용을 작성
• catch 코드 블록 안에는 try 코드 블록에서 발생한 에러를 처리하는 코드 작성
• finally 코드 블록 안에는 에러 발생과 상관없이 반드시 한 번 실행되는 코드 작성
// try catch finally 기본 사용법
console.log("-------------START---------------");
try {
console.log("-------------EXECUTED------------------");
} catch (e) {
console.error("-------------ERROR OCCURRED------------------");
} finally {
console.log("-------------FINALLY------------------");
}
try {
setTimeout(() => {
throw new Error("Error");
}, 1000);
} catch (e) {
console.error("캐치한 에러", e);
}
const err = new Error("오류 발생");
try {
throw new Error("오류 발생");
} catch (e) {
console.log(e.message);
}
Error 생성자 함수는 에러 객체를 생성하며, 에러 메시지를 전달할 수 있다.
Error 객체는 message 프로퍼티를 가지며 Error 객체 생성시 인수로 전달한 메시지를 나타낸다.
const err = new Error('Error')
Error 객체를 생성한다고 해서 에러가 발생하는 것은 아니며 에러를 발생시키려면 throw 문을 사용해 에러 객체를 던져야 한다.
throw 문 다음에는 표현식이 오며 표현식으로 만들어내는 값은 어떤 값이라도 상관 없지만 일반적으로 에러 객체를 지정한다.
try{
throw new Error('오류 발생');
}catch(e){
console.log(e.message);
}