여씨의 개발이야기

[동기와 비동기] new Promise(resolve => setTimeout(resolve, ms)); 이게 몬데요...?;;; 본문

🐾 Programming Lang/🛸 Javascript

[동기와 비동기] new Promise(resolve => setTimeout(resolve, ms)); 이게 몬데요...?;;;

yeossi 2022. 2. 14. 12:50

프로그래밍을 하면서 내가 제일 싫어하는 부분 또 또 나왔다... 일상에서도 시간 계산을 못 해서 그런 지(?) 개발을 할 때도 동기, 비동기 순서 이런 거 나오면 딱 질색이거등요... 그래도 엘리쌤 JS 강의 덕에 이전에 배웠던 동기와 비동기에 대해 복기하며 이해를 조금씩 하고 있었는데, async와 await 강의를 듣는 순간부터 멍때리는 시간이 많아졌다. 

promise? 그래 너. promise라는 클래스 너 이놈, asynchronous operation(: 비동기 연산자) 이라는 건 잘 알겠어... 안에서 이루어지는 작업이 성공 할 경우에 resolve, 실패할 경우에는 reject를 반환한다는 것도 okok,, 잘 알겠어. 대충 후속 처리 메서드(promise.then(...).catch(...).finally(...))를 사용한 promise chaining을 구성함로써 콜백hell 문제를 해결한다는 정도는 알고 있어... 

async, await도 대충 이해했는데 갑자기 promise가 나오면서 살짝 브레이크 밟는 중이었는데... 엥? 이게 뭐야.

new Promise(resolve => setTimeout(resolve, ms));

Promise 는 참고로 아래와 같이 선언되어있다. 

/**
 * Represents the completion of an asynchronous operation
 */
interface Promise<T> {
    /**
     * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
     * resolved value cannot be modified from the callback.
     * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).
     * @returns A Promise for the completion of the callback.
     */
    finally(onfinally?: (() => void) | undefined | null): Promise<T>
}

그리고 setTimeout은 아래와 같이 선언되어있다.

function setTimeout<TArgs extends any[]>(callback: (...args: TArgs) => void, ms?: number, ...args: TArgs): NodeJS.Timeout;
/**util.promisify no rest args compability
tslint:disable-next-line void-return**/

function setTimeout(callback: (args: void) => void, ms?: number): NodeJS.Timeout;

namespace setTimeout {
            const __promisify__: typeof setTimeoutPromise;
        }


그럼 promise 선언문을 다시 봐보자.

new Promise(resolve => setTimeout(resolve, ms));


💡 소스에서 setTimeout(resolve, 1000)은 1초 뒤에 resolve 함수를 실행하는 것을 의미한다.

이전에 배웠던 setTimeout은 setTimeout(()=>{...}, 1000)와 같이 setTimeout 내부에서 바로 함수를 생성하여 해당 함수를 1초 뒤에 실행하였는데, 위 소스와 같이 setTimeout(함수명, 지연시간)과 같이 이미 외부에 선언되어있는 함수를 실행할 수도 있다.

💡 resolve() 함수를 실행하는 것 자체 만으로도 Promise는 fullfilled 상태가 된다!

위의 코드를 처음 접할 때 제일 난감했던 것은 => 뒤에 resolve라는 이행함수에서 (...)의 행방인데, 이전에 Promise 내의 작업이 성공적으로 끝났을 경우에는 이행함수의 파라미터값을 return 해주는 것으로 배웠는데 왜 (...)의 행방이 묘연해졌을까? Promise를 다시 공부해보면 알 수 있었다...^^
Promise를 만들 때 resolve와 reject에 반환해 줄 매개변수가 필수로 있어야 하는게 아니었던 것이다. 물론, 보여줘야 할 값이 있으면 다르겠지만 timer 함수를 만들기 위해 아래와 같은 간단한 함수 선언시에는 state만 fullfilled 상태가 되는 것만 체크 할 resolve 함수만 넣어줘도 아무런 문제가 없는 것이다.

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms)); 
  // ms 만큼 delay되고 난 뒤에 state는 fullfilled가 된다.
}
Comments