티스토리 뷰

개발/자바스크립트

동기와 비동기

네스사 2023. 3. 20. 09:36

동기와 비동기 처리란?


  • 동기 처리란 특정 코드의 실행이 완료될 때까지 기다리고 난 후 다음 코드를 수행하는 것을 의미한다. 즉 하나하나 식 순차적인 작업을 수행하는 것.
  • 비동기 처리란 특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드들을 수행하는 것을 의미한다. 여러가지 작업을 동시에 수행하는 것.
  • JS는 싱글 스레드 기반이기에 기본적으로 동기적으로 작업을 처리한다. 그러나 비동기 처리는 전체적인 작업 시간 단축이 가능하기에 JS에서 구현이 가능하다. 

 

 

 

타이머 관련 API


브라우저에서 기본적으로 제공하는 API로 시간에 관한 기능을 비동기로 작동하도록 구성되었다. 

setTimeout(callback, millisecond)

  • 일정 시간 후에 함수를 실행하는 API. 밀리초단위로 설정이 가능하며, 임의의 타이머 ID을리턴한다.
const timer = setTimeout(function () {console.log('1초 후 실행');}, 1000);

clearTimeout(timerId)

  • setTimeout를 종료하는 API. setTimeout를 할당한 변수를 인자로 갖는다.
clearTimeout(timer)

setInterval(callback, millisecond),  clearInterval(timerId)

  • 일정 시간의 간격을 가지고 함수를 반복적으로 실행하는 API와 실행을 종료하는 API.
const timer = setInterval(function () {
	console.log('1초마다 실행');
}, 1000);
clearInterval(timer);

 

 

Callback


  • 가장 기초적인 비동기 처리 방식. 바깥에서 부터 안쪽까지 순차적으로 함수가 실행 된다.
  • 그러나 코드가 길어질 수록 복잡해지고 가독성이 낮아지는 Callback Hell때문에 지금은 잘 쓰이지 않는다.
const printString = (string, callback) => {
  setTimeout(function () {
    console.log(string);
    callback();
  }, Math.floor(Math.random() * 100) + 1);
};

const printAll = () => {
  printString('A', () => {
    printString('B', () => {
      printString('C', () => {
        printString('D', () => {
          printString('E', () => {
            printString('F', () => {
          });
        });
      });
    });
  });
};

printAll();// `아래와 같이 Callback 함수를 통해 비동기 코드의 순서를 제어할 수 있지만 코드가 길어질 수록 
//복잡해지고 가독성이 낮아지는 Callback Hell이 발생하는 단점이 있습니다.`

 

 

Promise


  • Callback Hell을 방지하는 역할도 수행하면서 비동기로 작동하는 코드를 제어할 수 있기하는 class
  • 비동기 처리를 수행할 콜백 함수를 인자로 받으며, 콜백 함수는 promise 내부에 있는 resolve, reject 함수를 인수로 사용한다.
  • promise 객체 생성시 코드가 정상적으로 처리가 되었다면 resolve 함수를 호출하고 에러가 발생했을 경우에는 reject 함수를 호출한다.
let promise = new Promise((resolve, reject) => {
	// 1. 정상적으로 처리되는 경우
	resolve(value);
	// 2. 에러가 발생하는 경우
 	reject(error);
});
  • Promise 객체는 stateresult라는 2개의 내부 프로퍼티를 가지며, 이는 .then, .catch, .finally같은 메서드를 사용해야만 접근이 가능하다.
  • state는 Promise의 작동 성공여부를 나타내며, 기본적으로 pending(대기)상태에 놓여 있다가,  콜백 함수가 성공적으로 작동했다면 fulfilled(이행)로 변경이 되고, 에러가 발생했다면 rejected(거부)가 된다.
  • result는 resolve,reject 함수가 호출될 때, 인자로 사용된다. resolve에서는 value, reject에서는 error가 된다.

 

then, catch, finally


  • then 은 Promise의 메서드로,  콜백함수에 작성했던 코드들이 정상적으로 처리가 되었다면 resolve 함수를 호출하고 .then 메서드로 접근한다.
  • .then 안에서 리턴한 값이 1. PromisePromise의 내부 프로퍼티 result를 다음 .then 의 콜백 함수의 인자로 받아오고, 2. Promise가 아니라면 리턴한 값을 .then 의 콜백 함수의 인자로 받아올 수 있다.
let promise = new Promise((resolve, reject) => {
	resolve("성공");
});

promise.then(value => {
	console.log(value);
	// "성공"
})
  • catch는 콜백함수에서 에러가 발생했을 때 reject 함수를 호출하고 .catch 메서드로 접근한다.
let promise = new Promise(function(resolve, reject) {
	reject(new Error("에러"))
});

promise.catch(error => {
	console.log(error);
	// Error: 에러
})
  • finally은 오류여부에 관계없이 접근이 가능한 메서드이다.
let promise = new Promise(function(resolve, reject) {
	resolve("성공");
});

promise
.then(value => {
	console.log(value);
	// "성공"
})
.catch(error => {
	console.log(error);
})
.finally(() => {
	console.log("성공이든 실패든 작동!");
	// "성공이든 실패든 작동!"
})
  • then과 catch,finally를 연결하여 사용하면 비동기 작업을 순차적으로 진행할 수 있다. 이를 Promise chaining이라 한다.

 

Promise.all


  • 여러 개의 비동기 작업을 동시에 처리하고 싶을때 사용.
  • 여러개의 Promise를 쓸 때보다, 시간 단축과 코드 중복을 완화할 수 있다.
  • 인자로는 배열을 받고, 해당 배열에 있는 모든 Promise에서 executor 내 작성했던 코드들이 정상적으로 처리가 되었다면 결과를 배열에 저장해 새로운 Promise를 반환한다.
  • 단, 열에 있는 Promise 중 하나라도 에러가 발생하게 되면 나머지 Promise의 state와 상관없이 즉시 종료된다.
Promise.all([
	new Promise((resolve, reject) => setTimeout(() => reject(new Error('에러1'))), 1000),
	new Promise((resolve, reject) => setTimeout(() => reject(new Error('에러2'))), 2000),
	new Promise((resolve, reject) => setTimeout(() => reject(new Error('에러3'))), 3000),
])
	.then((value) => console.log(value))
  .catch((err) => console.log(err));
	// Error: 에러1

 

 

Async/Await


  • Promise도 callback hell 같이 코드가 길어질수록 복잡해지고 가독성이 낮아지는 Promise Hell이라는 문제가 발생한다.
  • async/await 복잡한 Promise 코드를 간결하게 작성할 수 있게 도와준다.
  • async 키워드를 사용하고 async 함수 내에서만 await 키워드를 사용한다. 그러면 await 키워드가 작성된 코드가 동작하고 나서야 다음 순서의 코드가 동작하게 된다.
// 함수 선언식
async function funcDeclarations() {
	await 작성하고자 하는 코드
	...
}

// 함수 표현식
const funcExpression = async function () {
	await 작성하고자 하는 코드
	...
}

// 화살표 함수
const ArrowFunc = async () => {
	await 작성하고자 하는 코드
	...
}

'개발 > 자바스크립트' 카테고리의 다른 글

JSON  (1) 2023.03.22
fs 모듈과 fetch API  (0) 2023.03.21
프로토타입  (0) 2023.03.15
클래스  (0) 2023.03.15
고차 함수와 메서드  (0) 2023.03.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함