콜백(Callback)함수란?

다른 함수의 인자로 전달되는 함수이다. 

function main(callback) {
  callback();
}

main(() => console.log());

위 코드의 main 내부의 callback과 같은 인자로 전달되는 함수를 뜻한다.

 

비동기 콜백

콜백함수 자체는 비동기와 관련이 없으나, 요청과 결과가 동시에 주어지지 않는 비동기 작업에서 유용하게 사용된다.

function getData(callback) {
  setTimeout(() => {
    console.log('Received data from server!');
    callback();
  }, 1000);
}
getData(() => {
  console.log('Post process!');
});

// 결과: Received data from server! Post process!

위 예시의 getData()의 경우 setTimeout() 이라는 비동기 함수가 실행된다. setTimeout() 이후 console.log('Post process!') 를 실행하게 하려면  getData()의 인자에 실행하려는 작업(콜백함수)를 넣으면 된다.

 

콜백지옥

이처럼 비동기 작업에서 유용하게 쓰이는 콜백함수도 단점이 있다. 바로 지나친 콜백은 콜백지옥을 유발한다는 점이다.

function a(data, callback) {
  setTimeout(() => {
    callback(data);
   }, 1000);
}

function b(data, callback) {
  setTimeout(() => {
    callback(data);
   }, 1000);
}

function c(data, callback) {
  setTimeout(() => {
    callback(data);
   }, 1000);
}

a('A!!', (a) => {
  console.log(a);
  b('B!!', (b) => {
    console.log(b);
      c('C!!', (c) => {
        console.log(c);
       });
   });
});

// 결과: A!! B!! C!!

위 예시의 a, b, c 함수의 A!! B!! C!! 문구를 순서대로 출력하기 위해 콜백함수로 구성하였다. 비록 의도대로 작동은 하지만, 너무 많은 콜백으로 코드를 해석하기 쉽지 않다. 이러한 콜백지옥을 해결하기 위해 JavaScript에는 Promise 라는 객체가 존재한다. Promise에 대해서는 다음 글에서 정리하도록 하겠다.


출처

자바스크립트 비동기 프로그래밍 #2 | 비동기 콜백

동기(Synchronous) 란?

말 그대로 동시에 일어난다는 뜻으로, 작업에 대한 요청과 결과가 동시에 일어난다는 약속이다.

console.log('1');
console.log('2');
console.log('3');

// 결과: 1 2 3

위의 예제처럼 console.log('1')에 대한 작업이 요청되면 그 결과가 주어지고, 이후 console.log('2')에 대한 작업이 요청되는 방식이다.

비동기(Asynchronous) 란?

작업이 동시에 일어나지 않는다는 뜻으로, 작업에 대한 요청과 결과가 동시에 일어나지 않을 거라는 약속이다.

console.log('1');
setTimeout(() => {
	console.log('2');
}, 1000);
console.log('3');

// 결과: 1 3 2

위의 예제처럼 setTimeout()에 대한 작업이 요청되지만, 그 결과가 동시에 반환되는 대신 console.log('3')의 작업에 대한 결과가 반환되는 방식이다.

 

동기방식의 경우 요청에 따른 결과가 순서대로 반환되는 특성 상 직관적이고 단순한 설계가 가능하다. 하지만 통신, DB접근과 같이 오래 걸리는 작업의 경우 이후 작업들이 대기해야 하는 단점이 있기에 적절한 방식을 선택하여 작성해야 한다.

 

JavaScript에서의 동기와 비동기

JavaScript는 기본적으로 싱글쓰레드 언어이다. 이러한 자바스크립트에서 비동기 작업이 가능한 이유는 브라우저의 Web API 덕분이다. Web API는 웹 브라우저에서 제공하는 기능들로 setTimeout(), fetch()와 같은 비동기 메소드들을 제공한다. JavaScript 엔진은 이러한 비동기 함수들을 만나면 브라우저로 넘겨 별도의 브라우저 쓰레드에서 작동시킨다. 이를통해 싱글쓰레드인 JavaScript에서 비동기 프로그래밍을 가능하게 한다.

 

 


출처

자바스크립트 비동기 프로그래밍 #1 | 동기 vs 비동기

사실 논리연산자는 JavaScript에 국한되지 않지만, 때마침 JavaScript 공부중이라 JavaScript로 분류하였음.

(분류 안하면 죽는 병에 걸렸음)

우선 간단하게 JavaScript의 논리연산자에 대해 알아보자.

 

논리연산자

자바스크립트엔 ||(OR), &&(AND), !(NOT) 3가지의 연산자가 존재한다.

|| (OR)

result = a || b;

 

인수 중 하나라도 true이면 true를 반환, 그렇지않으면 false를 반환한다.

  True False
True True True
False True False

 

&& (AND)

result = a && b;

 

두 인수가 모두 참일 때 true 반환, 그렇지않으면 false를 반환한다.

  True False
True True False
False False False

 

! (NOT)

result = !value;

 

인수를 하나만 받으며, 피연산자를 Boolean(True/False) 타입으로 변환 후 그 값의 역을 반환한다.

  True False
  False True

 

 

쇼트서킷

쇼트서킷이란 좌측 피연산자만으로 결과과 확정된 논리연산자의 경우, 우측 피연산자를 확인하지 않는 기능.

한마디로 불필요한 연산을 생략함으로써 성능을 개선하는 연산 방식이다.

true || true; // true
true || false; // true

false && true; // false
false && false; // false

 

- ||(OR)의 경우 좌측 피연산자가 true일 경우 항상 true를 반환.

- 반대로 &&(AND)의 경우 좌측 피연산자가 false일 경우 항상 false를 반환.

이미 결과가 확정된 상황에서 우측 피연산자를 계산하는 것은 얼마나 비효율적인 일인가...

 

JavaScript는 이러한 비효율을 개선하기 위해 쇼트서킷을 지원한다. (JavaScript 뿐만 아니라 대부분의 언어가 쇼트서킷을 지원)

 

 

믿기 함들다면 당장 브라우저 콘솔창을 열어 아래 코드를 입력하여 확인해보자.

true || console.log('test'); // true
console.log('test') || true; // console.log('test') 실행 후 true

false && console.log('test'); // false
console.log('test') && false; // console.log('test') 실행 후 undefined

위 코드가 console.log('test')와 같은 단순한 코드라 실감이 안갈 수 있다.

하지만 만약 console.log('test') 대신 수백 초가 걸리는 함수 혹은 파일입출력 등 시간이 많이 걸리는 작업이라면?

코드의 순서를 바꾸기만 하더라도 수백초의 시간을 절약할 수 있다.

 

정리

||(OR)연산자의 경우 좌측에 true값을, &&(AND) 연산자의 경우 좌측에 false값을 놓자.

수백 초의 시간을 절약할 수도 있다.

자바스크립트에서 문자열을 숫자로 바꾸는 방법에는 여러가지가 존재한다.

 

parseInt()

- 인자를 integer 타입으로 parse하는 함수.
- 파싱결과가 정수가 아닐경우 버림한 후 정수로 반환.
- integer 또는 NaN을 리턴한다.
parseInt('3'); // 3

parseInt('3.14'); // 3

parseInt(3.99); // 3

parseInt('가나다'); // NaN

parseInt('3.14는 파이'); // 3

 

parseFloat()

- string 타입의 인자를 float 타입으로 parse하는 함수.
- parseInt()와 다르게 정수+실수 모두 반환 가능.
- integer 또는 NaN을 리턴한다.
parseFloat('3.14'); // 3.14

parseFloat('3'); // 3

parseFloat(3.99); // 3.99

parseFloat('가나다'); // NaN

parseFloat('3.14는 파이); // 3.14

 

Number()

- 인자를 숫자(정수+실수)로 바꿔준다.
- integer, float 또는 NaN을 리턴한다.
Number('3'); // 3

Number('3.14'); // 3.14

Number('가나다'); // NaN

Number('3.14는 파이'); // NaN

 

정리

 
parseInt()

parseFloat() Number()
공통점
인자로 들어온 값을 숫자로 반환

차이점 • 정수값만 반환 (실수의 경우 버림하여 반환)

숫자+문자의 경우 숫자 반환 (정수만 반환)
 정수+실수 모두 반환

 숫자+문자의 경우 숫자 반환
 정수+실수 모두 반환

 숫자+문자의 경우 NaN 반환

 

Date Object란

날짜 혹은 시간과 관련된 정보를 제공해주는 객체

 

생성방법

let today = new Date();	// 현재시간 저장

let myBirthDay = new Date("1997/1/13");

let anniversary = new Date(2018, 04, 20);

위와같이 여러 방법으로 사용이 가능하나, 나는 특정날짜를 가져올 경우 마지막 방법을 선호한다.

 

 

 

Date Object를 생성했다면 이를 이용할 메소드들을 알아보자.

메소드

// 연도
getFullYear(), setFullYear()

// 현재 월 - 1
getMonth(), setMonth()

// 일
getDate(), setDate()

// 요일(0~6), 요일은 setDay()가 없다
getDay()

// 시
getHours(), setHours()

// 분
getMinutes(), setMinutes()

// 초
getMinutes(), setMinutes()

// 밀리초(1/1000초)
getMilliseconds(), setMilliseconds()

// 1970년 1월 1일 부터 경과한 밀리초 시간
getTime(), setTime()

// GMT 표기방식으로 표현된 문자형 시간
toGMTString()

// 운영시스템 표기방식으로 표현된 문자형 시간
toLocaleString()

 

가령 특정일 까지의 시간을 계산하고 싶을 경우 아래와 같이 getTime()을 통해 계산한다.

이후 결과값인 밀리초를 시, 분, 초 로 나누어 계산하면 된다.

let xMas = new Date(2023, 12, 25);
let today = new Date();

let diff = xMas.getTime() - today.getTime();

 

+ Recent posts