Javascript

짧게 짧게 알게 된 것 정리 1

min' 2022. 11. 25. 06:36
728x90
반응형

- Javascript는 동기식 언어이다!

자바스크립트는 한 번에 하나의 작업을 수행

한 작업이 실행되는 동안 다른 작업은 멈춘 상태를 유지하고 자신의 차례를 기다리는

 

=> 단일 스레드(싱글 스레드), 동기(Synchronous)

 

console.log("hi");
console.log("hello");
console.log("bye")

이렇게 console.log()를 세 개를 입력하고, 출력 결과를 확인해보면 순서대로 "hi", "hello", "bye"가 찍힘

 

이렇게 나오는 이유는 Javascript의  Engine(V8) 주요 구성 요소가 Memory Heap Call stack이기 때문

 

- Memory Heap : 변수와 객체의 메모리 할당을 담당하는 곳

 

- Call Stack : 함수가 호출이 되면 쌓이는 곳. 함수가 쌓이는 순서와는 반대로 실행

자바스크립트에서 함수를 호출하면 Call Stack이라는 곳에 호출 순서대로 차곡차곡 쌓임

그 후 Stack은 맨 마지막에 호출된 함수가 가장 먼저 반환

List in First Out, 먼저 들어온 것이 먼저 나간다는 의미 => LIFO 구조

 

1. 처음에 console.log("hi")가 호출되면서 Call Stack에 먼저 쌓이고,

hi를 반환하면 console.log("hi")는 Call Stack에서 사라짐

hi를 반환하기 전까지 다음 작업은 수행할 수 없음. 이 순서대로 console.log("hi")가 사라지고 hi를 반환

 

2. 그 후, console.log("hello")가 쌓이고 hello를 반환하면, console.log("hello")가 사라짐

 

3. 또, 그 후 console.log("bye")가 쌓이고 bye를 반환하면 console.log("bye")가 마지막으로 사라짐

 

 

- 그렇다면 비동기는 무엇인가?

 

비동기는 어떠한 요청을 보내면 그 요청이 끝날 때까지 기다리는 것이 아니라,

응답에 관계 없이 바로 다음 동작이 실행되는 방식을 말함

 

비동기는 필요한가?

 

웹 페이지가 로딩되거나 어떠한 동작(event) 하나가 30초 이상 걸린다고 생각해보면웹 페이지는 이 동작이 끝날 때까지 화면에 나타나지 않거나 다음 동작을 수행하는데 지장을 줌또한, 사용자들은 느리고 응답 없는 웹 사이트를 원하지 않음

그렇기 때문에 웹 사이트에서 자바스크립트가 비동기적으로 동작해야 함

 

그런데 브라우저에서 Javascript가 어떻게 화면 전환하면서

HTTP 요청이나 여러 이벤트를 동시에 동작을 할 수 있는 것인가?

 

그것은 바로 자바스크립트의 실행 환경(Runtime)과 관련되어 있음

브라우저는 자바스크립트의 엔진 만으로 동작하지 않음

운 좋게도 브라우저에서의 자바스크립트 실행 환경(Runtime)에서는

자바스크립트 엔진 자체가 제공하지 않는 일부 기능인 DOM 조작이나 AJAX 같은 비동기 처리를 위한 web API를 제공

 

또한, 이를 제어하기 위해 이벤트 루프(Event Loop), 이벤트 큐(Callback Queue 혹은 task Queue)가 존재

모든 Web API는 작동이 완료되면 callback을 task queue에 밀어 넣음

 

- 이벤트 루프(Event Loop) : call stack과 tack queue를 주시하는 작은 파트

즉, stack(스택)이 비어있으면, task queue의 첫 번째 call back부터 stack(스택)에 쌓아 효과적으로 실행할 수 있게 해 줌

 

보시는 봐와 같이 현재 stack(스택)이 비어있고, tack queue에는 callback이 하나가 있음

여기서 이제 이벤트 루프(Event Loop)가 자신이 할 일을 생긴 것을 인지하고 callback을 stack(스택)에 넣기 시작

stack(스택)은 엄연히 자바스크립트 영역

다시 자바스크립트 엔진(V8)으로 돌아가서, console.log("there")을 실행

이제 콘솔 창에 there이 찍히고 stack에서 모두 사라짐

 

 

- 프라미스란 무엇인가?

 

본인을 아주 유명한 가수라고 가정해 봅시다.
그리고 탑 가수인 본인이 밤, 낮으로 다음 싱글 앨범이 언제 나오는지 물어보는 팬들을 상대해야 한다고 해 봅시다.

당신은 앨범이 출시되면 팬들이 자동으로 소식을 받아볼 수 있도록 해 부하를 덜 겁니다.
구독 리스트를 하나 만들어 팬들에게 전달해 이메일 주소를 적게 하고, 앨범이 준비되면 리스트에 있는 팬들에게 메일을 보내
앨범 관련 소식을 바로 받아볼 수 있게 하는 식으로 말이죠. 이렇게 하면 녹음 스튜디오에 화재가 발생해서 출시 예정인 앨범이
취소되는 불상사가 발생해도 관련 소식을 팬들에게 전달 할 수 있습니다.

이제 모두가 행복해졌습니다. 밤낮으로 질문을 하는 팬이 사라졌고, 팬들은 앨범 출시를 놓치지 않을 수 있게 되었으니까요.

이 비유는 코드를 작성하면서 자주 만나는 상황을 실제 일어날 법한 일로 바꾼 것입니다. 바로 아래 같은 상황 말이죠.

 

'제작 코드(producing code)'는 원격에서 스크립트를 불러오는 것 같은 시간이 걸리는 일을 함.

위 비유에선 '가수’가 제작 코드에 해당.

 

'소비 코드(consuming code)'는 '제작 코드’의 결과를 기다렸다가 이를 소비.

이때 소비 주체(함수)는 여럿이 될 수 있습니다. 위 비유에서 소비 코드는 '

 

프라미스(promise)'제작 코드’와 '소비 코드’를 연결해 주는 특별한 자바스크립트 객체.

위 비유에서 프라미스는 '구독 리스트’.

'프라미스’는 시간이 얼마나 걸리든 상관없이 약속한 결과를 만들어 내는 '제작 코드’가 준비되었을 때,

모든 소비 코드가 결과를 사용할 수 있도록 해줍니다.

 

사실 프라미스는 구독 리스트보다 훨씬 복잡하기 때문에, 위 비유가 완벽하게 들어맞지는 않음

프라미스에는 더 많은 기능이 있고 한계도 있음

 

promise 객체는 아래와 같은 문법으로 만들 수 있음

let promise = new Promise(function(resolve, reject) {
  // executor (제작 코드, '가수')
});

 

 

- asunc await은 무엇인가?

 

async와 await라는 특별한 문법을 사용하면 프라미스를 좀 더 편하게 사용할 수 있음

이해하기 쉽고 사용법이 어렵지도 않음

 

- async 함수

async 키워드부터 알아보자. async는 function 앞에 위치

async function f() {
  return 1;
}

function 앞에 async를 붙이면 해당 함수는 항상 프라미스를 반환.

프라미스가 아닌 값을 반환하더라도 이행 상태의 프라미스(resolved promise)로 값을 감싸

이행된 프라미스가 반환되도록 함.

아래 예시의 함수를 호출하면 result가 1인 이행 프라미스가 반환.

async function f() {
  return 1;
}

f().then(alert); // 1

명시적으로 프라미스를 반환하는 것도 가능한데, 결과는 동일

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

async가 붙은 함수는 반드시 프라미스를 반환하고, 프라미스가 아닌 것은 프라미스로 감싸 반환.

그런데 async가 제공하는 기능은 이뿐만이 아님. 또 다른 키워드 await는 async 함수 안에서만 동작

 

- await

 

await 문법은 다음과 같음

// await는 async 함수 안에서만 동작합니다.
let value = await promise;

자바스크립트는 await 키워드를 만나면 프라미스가 처리될 때까지 기다림 (await는 '기다리다’라는 뜻을 가진 영단어).

결과는 그 이후 반환

1초 후 이행되는 프라미스를 예시로 사용하여 await가 어떻게 동작하는지 살펴보자

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });

  let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)

  alert(result); // "완료!"
}

f();

함수를 호출하고, 함수 본문이 실행되는 도중에 (*)로 표시한 줄에서 실행이 잠시 '중단’되었다가

프라미스가 처리되면 실행이 재개. 이때 프라미스 객체의 result 값이 변수 result에 할당.

따라서 위 예시를 실행하면 1초 뒤에 '완료!'가 출력.

 

await는 말 그대로 프라미스가 처리될 때까지 함수 실행을 기다리게 만듦.

프라미스가 처리되면 그 결과와 함께 실행이 재개. 프라미스가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않음.

 

await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법.

promise.then보다 가독성 좋고 쓰기도 쉬움.

 

 

- Date.now()란 메소드는 무엇인가?

 

now() 메소드는 1970년 1월 1일 0시 0분 0초부터 현재까지 경과된 밀리 초를 Number 형으로 반환

now()는 Date의 정적 메소드이기 때문에, 항상 Date.now() 처럼 사용해야 함

 

Date 객체와 날짜

 

날짜를 저장할 수 있고, 날짜와 관련된 메서드도 제공해주는 내장 객체 Date

Date 객체를 활용하면 생성 및 수정 시간을 저장하거나 시간을 측정할 수 있고,

현재 날짜를 출력하는 용도 등으로도 활용할 수 있음

 

객체 생성하기

 

new Date()를 호출하면 새로운 Date 객체가 만들어지는데, new Date()는 다음과 같은 형태로 호출할 수 있음

인수 없이 호출하면 현재 날짜와 시간이 저장된 Date 객체가 반환

let now = new Date();
alert( now ); // 현재 날짜 및 시간이 출력됨

 

 

 

 

 

- getCommentList 클래스란 무엇인가?

현재 페이지에서 읽기 전용 주석 목록을 반환.

 

 

- cmtObj.profileImg ?? "/assets/blankProfile.webp" 

이게 아니면 이거 보여줘!

728x90
반응형