promise(+new연산자), 동기, 비동기에 대하여..

Jetom·2024년 7월 12일
0

개념정리(js)

목록 보기
20/20
post-thumbnail
post-custom-banner

예전 블로그 글에 promise 공부를 했을 때, 정리해서 올린 내용이 있었는데, 시간이 지난 지금 이해하고 적은게 아닌것같아 다시 정리해 보려한다. 헤헷😏


동기(Synchronous)

Synchronous 자체를 번역하면 동시성 / 동시의 이라는 단어가 나오는데 gpt에게 물어보면 '하나 하나 순차적으로 실행된다는 뜻'이라고한다. 다음은 gpt와 각종 블로그의 정보를 참고 + 조합해서 나온 동기가 무엇인지에 대해 간단히 정리하자면 아래와 같다.🤔

  • 각 작업이 순차적으로 실행
  • 현재 작업이 끝나야 다음 작업이 시작
  • 호출한 함수 또는 작업이 반환될 때까지 대기하는 동안 실행 흐름이 차단되는 특징이 있다.

그럼 다음 코드를 살펴보자.


console.log("hello")

for(let i = 0; i < 10000; i++){
	//동기적으로 처리하기 위한 코드
}

console.log("Hi")

이렇게 hello -> for문 -> Hi가 찍히기도 하지만

console.log("Hi");
alert("확인 안누르면 다음 콘솔 안찍힐걸?!");
console.log("으악 찍힘");

alert을 사용해 확인할 수도 있다. alert은 브라우저의 기본 내장 API이며, JS로 사용자와 상호작용할 수 있도록 설계된 동기 함수이다. 따라서 Web API와는 다르다.(alert과 더불어 prompt, confirm이 있다.)


비동기(Asynchronous)

비동기는 동기의 반대의 개념이니, 동시에 일어나지 않는다는 뜻이다! 그렇다면 동시에 처리할 수 있다는 뜻도 되고, 긴 작업이 진행되는 다른 무엇을 기다리는 동안 다른 작업을 동시에 실행할 수 있다는 뜻이된다.

  • 작업의 완료 여부를 기다리지 않고 다른 작업을 실행할 수 있는 방식
  • 작업이 시작되면 해당 작업이 완료될 때까지 기다리지 않고 다음 코드를 실행
  • 주로 I/O 작업이나 네트워크 요청과 같이 시간이 오래 걸리는 작업에 쓰임

비동기 코드의 예시는 아래와 같다.

//I/O 작업이나 네트워크 요청이라고 했으니 fetch로 예시를 들었다.
console.log("얏호");

fetch('서버로부터 요청할 URL')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error('Error:', err));

console.log("끗!");

위와 같이 네트워크 요청 fetch가 있다면
얏호 -> 끗 -> 네트워크 요청 완료 후 데이터 출력
순으로 나오게 될것이다. fetch 함수는 Promise를 반환한다. 이 Promise는 바로 다음 내용에서 살펴보자.


Promise

Promise는 비동기 작업의 결과를 나타내는 객체이다. promise는 객체가 생성될 때 내부의 executor 함수가 즉시 실행된다. 그래서 executor 함수는 promise를 생성하는 순간 동기적으로 실행된다고한다. 나는 여기서 신선한 충격을 받았다. promise -> 비동기라는 생각이 있었는데, 동기적으로 실행 후 .then이나 .catch로 비동기 처리가 이어진다니.. 너무 신기했다. 그런고로 promise에 대해 다시 내용을 정리하려한다.

executor 👉 집행자라는 영어 뜻을 가지며, 여기선 Promise 객체를 생성할 때 전달하는 함수이다. 이 함수는 Promise의 실행자 함수라고 하며, 'resolve', 'reject'라는 두 개의 콜백 함수를 인수(=Argument)로 받는다.

다음 예시 코드를 보면서 다시 살펴보자

const myPromise = new Promise((resolve, reject) => {  
  	//executor함수!
    const data = fetch('서버로부터 요청할 URL');
    
    if(data){
      resolve(data);
    }
    	
    else{
      reject("Error");
    } 
})

이 코드를 해석하면 다음과 같다.
1. new Promise가 호출될 때 executor 함수가 즉시 실행됨
2. executor 함수 내부에서 비동기 작업(여기선 fetch 함수가 네트워크 요청하는 것)
3. 작업이 성공하면 resolve에 data가 나올것이고, 이게 아니라면 reject의 error가 호출될 것이다.


new 연산자

Promise의 로직을 보면 new가 붙은걸 볼 수 있는데, 이것은 new 연산자라고 한다. new 연산자는 생성자 함수를 호출할 때 사용되는것으로 생성자 함수를 호출해 새로운 객체를 생성하는 역할을 한다. (따지고보면 new 연산자 !== 생성자 함수이다.)

다음은 new 연산자가 어떻게 동작하는지에 대한 간단한 과정이다.

새로운 객체 생성 -> 프로토타입 연결 -> this 바인딩 -> 생성자 함수 실행 -> 객체 반환 순이다.

다음은 세부 설명이다.

  1. 새로운 객체 생성

    • 빈 객체가 생성되며, 이 객체는 나중에 생성자 함수가 가리키는 프로토타입을 상속받게 된다.
    let obj = {};
  2. 프로토타입 연결

    • 생성된 빈 객체의 던더 프로토가 생성자 함수의 'prototype' 속성을 가리키도록 설정된다.
    //이렇게 언더바 두 개가 있는것을 던더 프로토라고 한다.
    obj.__proto__ = ConstructorFunction.prototype;
    
  3. this 바인딩

    • 생성자 함수가 호출될 때 'this'가 새로 생성된 객체로 바인딩됨
  4. 생성자 함수 실행

    • 생성자 함수의 코드가 실행됨. 이 과정에서 객체 초기화가 이루어짐
  5. 객체 반환

    • 생성자 함수가 객체를 명시적으로 반환하지 않으면 'new' 연산자는 새로 생성된 객체를 반환함
profile
사람이 좋은 인간 리트리버 신혜리입니다🐶
post-custom-banner

0개의 댓글