ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • promise 구현 코드 해석
    JavaScript 2023. 8. 25. 08:57
    // executor => executor 함수는 비동기 작업을 시작하고 해당 작업이 완료되면 resolve(pending -> fullfilled) 또는 reject(pending -> rejected) 함수를 호출하여 Promise의 상태를 결정하는 역할을 합니다.
    // executor 함수 내부에서의 비동기 작업은 보통 타이머 함수(setTimeout), 네트워크 요청, 파일 읽기 등이 될 수 있습니다.
    function Promise(executor) {
      // 프로미스 객체가 생성될 떄, 객체의 상태, 결과, 에러 , 리스터를 관리합니다.
      this.status = "pending";
      this.result = null;
      this.error = null;
      this.listeners = new Set();
    
      //executor 함수 내에서 resolve와 reject 현재 Promise 객체의 컨텍스트에 바인딩하여 전달합니다.
      // executor 함수 내에서 resolve를 호출하면(pending -> fullfilled) 해당 promise 상태와 결과값을 제어할 수 있습니다.
      // executor 함수 내에서 reject를 호출하면(pending -> rejected) 해당 promise 상태와 결과값을 제어할 수 있습니다.
      executor(this.resolve.bind(this), this.reject.bind(this));
    }
    
    // Promise 프로토타입 객체에 then 메서드를 추가하는 과정입니다.
    // 두개의 매개변수 onFulfilled와 onRejected. 이들은 Promise가 이행될 때와 거부될 때 호출될 콜백 함수입니다.
    Promise.prototype.then = function (onFulfilled, onRejected) {
      // fn() 함수는 then메서드 내부에서 정의되는 중간함수로 나중에 등록된 리스너로 사용됩니다.
      function fn() {
        // promise 객체의 상태가 fullfilled 인경우, onFulfilled 콜백함수를 호출하며 this.result 값을 인자로 전달합니다.
        // 비동기 작업이 완료되어 결과가 있을떄 해당 콜백함수가 실행됩니다.
        if (this.status === "fulfilled") {
          onFulfilled(this.result);
        }
    
        // promise 객체의 상태가 rejected인 경우,
        // onRejected 함수가 등록되어 있다면 해당 함수를 호출하며, this.error 값을 인자로 전달합니다. 그렇지 않은 경우에는 onRejected가 없을 때 this를 반환합니다. 이로써 catch가 없는 경우에도 체인을 유지할 수 있습니다.
        if (this.status === "rejected") {
          if (!onRejected) {
            return this;
          }
          onRejected(this.error);
        }
      }
    
      //  this.listener에 fn 함수를 바인딩하여 등록하는 부분입니다.
      // fn 함수는 상태 변화에 따라 호출 될 함수 리스트에 추가됩니다.
      this.listeners.add(fn.bind(this));
    
      // then 메서드는 this (현재의 Promise 객체)를 반환하여 메서드 체인을 가능하게 합니다. 이로써 연속적으로 then을 호출하거나 catch를 체인으로 연결할 수 있게 됩니다.
      return this;
    };
    
    // Promise의 프로토타입 객체에 catch 메서드를 정의하고 있는 부분입니다. 이 메서드는 onRejected 콜백 함수를 받아서 처리합니다.
    Promise.prototype.catch = function (onRejected) {
      // fn 함수는 catch 메서드 내부에서 정의되는 중간 함수입니다. 이 함수는 나중에 등록된 리스너로 사용됩니다.
      function fn() {
        // 상태가 'rejected'가 아닌 경우에는 함수 실행을 중단하고 return하여 함수를 빠져나옵니다. 이로써 'rejected' 상태가 아닐 때는 아무런 동작도 하지 않습니다.
        if (this.status !== "rejected") {
          return;
        }
    
        // Promise 객체의 상태가 'rejected'일 때, 위 줄은 onRejected 콜백 함수를 호출하며 this.error 값을 인자로 전달합니다. 이로써 비동기 작업이 실패한 경우 해당 콜백 함수가 실행됩니다.
        onRejected(this.error);
    
        //catch 메서드 내에서 this (현재의 Promise 객체)를 반환하여 메서드 체인을 유지하게 합니다. 이로써 catch 메서드 또한 다른 메서드와 연결하여 사용할 수 있습니다.
        return this;
      }
    
      //  this.listener에 fn 함수를 바인딩하여 등록하는 부분입니다.
      // fn 함수는 상태 변화에 따라 호출 될 함수 리스트에 추가됩니다.
      this.listeners.add(fn.bind(this));
    };
    
    // Promise의 프로토타입 객체에 publish 메서드를 정의하고 있는 부분입니다.
    Promise.prototype.publish = function () {
      // forEach 메서드를 사용하여 this.listeners에 등록된 모든 리스너 함수들을 순회합니다. 각 리스너 함수 listener를 실행시킵니다.
      this.listeners.forEach((listener) => {
        listener();
      });
    };
    
    // Promise의 프로토타입 객체에 resolve 메서드를 정의하고 있는 부분입니다.
    // Promise 객체를 성공적으로 이행(resolve) 상태로 변경하고, 결과 값을 설정하여 미래의 then 콜백 함수에 전달하는 역할을 합니다.
    Promise.prototype.resolve = function (value) {
      // resolve 메서드 내부에서 Promise 객체의 상태와 결과 값을 설정하는 부분입니다.
      // this.status를 "fulfilled"로 변경하여 Promise 객체의 상태를 이행 상태로 표시하고, this.result에 전달된 value 값을 저장합니다.
      // 이렇게 함으로써 비동기 작업의 결과를 나타내는 값이 Promise 객체에 설정됩니다.
      this.status = "fulfilled";
      this.result = value;
    
      // this.publish()는 등록된 리스너 함수들을 실행시켜 Promise 객체의 상태 변화를 알리는 역할을 합니다. publish 메서드를 호출함으로써 onFulfilled 콜백 함수들이 실행되게 됩니다.
      // 이로써 비동기 작업이 성공적으로 완료되어 결과가 있는 경우, then 메서드에 등록된 함수들이 실행되게 됩니다.
      this.publish();
    };
    
    // Promise의 프로토타입 객체에 reject 메서드를 정의하고 있는 부분입니다.
    // 이 메서드는 Promise 객체를 거부(reject) 상태로 변경하고, 에러 정보를 설정하여 미래의 catch 콜백 함수에 전달하는 역할을 합니다.
    Promise.prototype.reject = function (error) {
      // reject 메서드 내부에서 Promise 객체의 상태와 에러 정보를 설정하는 부분입니다.
      // this.status를 "rejected"로 변경하여 Promise 객체의 상태를 거부 상태로 표시하고, this.error에 전달된 error 값을 저장합니다.
      // 이렇게 함으로써 비동기 작업이 실패한 경우에 대한 에러 정보가 Promise 객체에 설정됩니다.
      this.status = "rejected";
      this.error = error;
    
      // 등록된 리스너 함수들을 실행시켜 Promise 객체의 상태 변화를 알리는 역할을 합니다. publish 메서드를 호출함으로써 onRejected 콜백 함수들이 실행되게 됩니다.
      this.publish();
    };
    
    // 비동기적인 상황을 시뮬레이션하여, 랜덤한 값을 생성하고 그에 따라 Promise 객체가 이행 또는 거부되는 예제입니다.
    // 코드 실행 결과에 따라 resolve 또는 reject 상태로 이행된 Promise 객체의 상태에 따라 then 또는 catch 메서드를 통해 콜백 함수를 실행할 수 있습니다.
    
    // Promise 생성자 함수는 콜백 함수를 인자로 받는데, 이 콜백 함수는 비동기 작업을 정의하고 그 결과에 따라 resolve 또는 reject 함수를 호출하여 Promise 객체의 상태를 결정합니다.
    const num = new Promise((resolve, reject) => {
      setTimeout(() => {
        const randomNumber = Math.random();
    
        if (randomNumber > 0.5) {
          resolve(randomNumber);
        } else {
          reject("0.5보다 작습니다.");
        }
      }, 600);
    });

     

Designed by Tistory.