Part 1 - 타이머 API

Jelkov Ahn·2021년 10월 14일
1

JS/NODE 비동기

목록 보기
3/6
post-thumbnail

타이머 종류

(1) setTimeout(callback, millisecond)
일정 시간 후에 함수를 실행

  • arguments: 실행할 callback 함수, callback 함수 실행 전 기다려야 할 시간 (밀리초)
  • return value: 임의의 타이머 ID
setTimeout(function () {
  console.log('1초 후 실행');
}, 1000);
// 123

(2) setInterval(callback, millisecond)
일정 시간의 간격을 가지고 함수를 반복적으로 실행

  • arguments: 실행할 callback 함수, 반복적으로 함수를 실행시키기 위한 시간 간격 (밀리초)
  • return value: 임의의 타이머 ID
setInterval(function () {
  console.log('1초마다 실행');
}, 1000);
// 345

(3) clearInterval(timerId)
반복 실행중인 타이머를 종료

  • arguments: 타이머 ID
  • return value: 없음
const timer = setInterval(function () {
  console.log('1초마다 실행');
}, 1000);
clearInterval(timer);
// 더 이상 반복 실행되지 않음
setTimeout에 대응하는 clearTimeout도 있음

part1 - 타이머API

01_callback.js 파일

const delay = (wait, callback) => {
  setTimeout(callback, wait);
}

02_promiseConstructor.js 파일

const sleep = (wait) => {
  return new Promise((resolve) => {
    setTimeout(resolve, wait);
  });
}

script.js 파일

let player = document.querySelector('#player');
let title = document.querySelector('#title');

let btnCallback = document.querySelector('#btnCallback');
btnCallback.onclick = runCallback;

let btnPromise = document.querySelector('#btnPromise');
btnPromise.onclick = runPromise;

let btnAsync = document.querySelector('#btnAsync');
btnAsync.onclick = runAsync;

function runCallback() {
  resetTitle();
  playVideo();

  delay(1000, () => {
    pauseVideo();
    displayTitle();

    delay(500, () => {
      highlightTitle();

      delay(2000, resetTitle);
    });
  });
}

function runPromise() {
  resetTitle();
  playVideo();

  sleep(1000).then(() => {
    pauseVideo();
    displayTitle();
  })
    .then(sleep.bind(null, 500))
    .then(highlightTitle)
    .then(sleep.bind(null, 2000))
    .then(resetTitle)
}

async function runAsync() {
  resetTitle();
  playVideo();

  await sleep(1000);
  pauseVideo();
  displayTitle();

  await sleep(500);
  highlightTitle();

  await sleep(2000);
  resetTitle();
}


function resetTitle() {
  log('제목을 초기화합니다');
  title.classList.remove('visible', 'highlight');
}

function playVideo() {
  log('영상을 재생합니다');
  player.play();
}

function pauseVideo() {
  log('영상을 멈춥니다');
  player.pause();
}

function displayTitle() {
  log('제목을 표시합니다');
  title.classList.add('visible');
}

function highlightTitle() {
  log('제목을 강조합니다');
  title.classList.add('highlight');
}

function log(message) {
  let logger = document.querySelector('#logger');
  let l = document.createElement('div');
  l.textContent = `[${new Date().toISOString().slice(11, -5)}] ${message}`;
  logger.prepend(l);
}
  • 1. callback, Promise, async & await 버튼들은 정확히 동일한 액션을 하지만, 그 구현 방법은 조금씩 다릅니다.
    • callback 버튼은 runCallback 함수를 실행합니다.
    • promise 버튼은 runPromise 함수를 실행합니다.
    • async & await 버튼은 runAsync 함수를 실행합니다.

  • 2. delay 함수와 sleep 함수의 차이점을 확인해 보세요.

Thread.Sleep은 해당 스레드를 차단하고 시간을 기다린다. (blocking)
Task.Delay는 해당 스레드에게 흐름을 넘기고 논리적으로 시간을 기다린다. (non-blocking)

Thread.Sleep

class Program

    {
        static void Main(string[] args)

        {
            Program p = new Program();
            p.Go();
        }

        void Method()
        {
            Thread.Sleep(3000);
            Console.WriteLine("Method()");
        }

        void Go()
        {
            Method();  // 3초간 기다린후 "Method()" 호출이 된 이후에야 스레드가 진행되는 것을 확인 할 수 있다.
            while (true)

            {
                Thread.Sleep(300);
                Console.Write("1");  // 0.3초마다 "1"을 출력하는 스레드에서 Thread.Sleep 호출.
            }

        }

    }

Task.Delay

class Program

    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Go();
        }
        
        async void MethodAsync()
        {
            await Task.Delay(3000);
            Console.WriteLine("MethodAsync()");
        }

        void Go()
        {
            MethodAsync();
            while (true)
            {
                Thread.Sleep(300);
                Console.Write("1");
            }
        }
    }

Task.Delay를 비동기적으로 실행해 주니 "1"을 출력하는 흐름을 막지 않고 3초가 지난 이후에 "MethodAsync()"가 출력되는 모습이 보인다.

  • 3. runAsync 함수는 async 및 await 키워드의 사용법을 보여 줍니다. 비동기 함수가 마치 동기 함수처럼 작동합니다. 그러나 실제로는 Promise를 이용하여 결과를 리턴합니다.

Bare Minimum Requirements

  • Q) Promise 실행함수가 가지고 있는 두 개의 파라미터 resolve 와 reject 는 각각 무엇을 의미하나요?

resolve함수는 Promise 실행함수가 fulfilled(이행) 되었을 때 결과를 값으로 반환하는 함수이고,
reject는 Promise 실행함수가 rejected(거부) 되었을 때 오류의 원인을 반환하는 함수이다.

Promise를 사용하는 두가지 방법

(1) new Promise(function(resole, reject))
(2) Promise.resolve(function())

new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject입니다.

Promise.resolve()

resolve의 역할은 주어진 값으로 이행하는 Promise 객체를 반환한다.

주어진 값으로 이행하는 Promise 객체를 반환합니다.
값이 then 가능한 (즉, then 메서드가 있는) 경우, 반환된 프로미스는 then 메서드를 따라가고 마지막 상태를 취합니다.
그렇지 않은 경우 반환된 프로미스는 주어진 값으로 이행합니다.
어떤 값이 프로미스인지 아닌지 알 수 없는 경우, Promise.resolve(value) 후 반환값을 프로미스로 처리할 수 있습니다.

Promise.reject()

reject는 주어진 이유로 거부하는 Promise 객체를 반환합니다.

  • Q) resolve, reject함수에는 인자를 넘길 수 있습니다. 이때 넘기는 인자는 어떻게 사용할 수 있나요?

    • resolve 와 reject 에서 전달된 인자는 .then() 에 전달하는 Callback에서 인자로 받을 수 있다.
  • Q)new Promise()를 통해 생성한 Promise 인스턴스에는 어떤 메소드가 존재하나요? 각각은 어떤 용도인가요?

    • Promise.prototype.catch() <- Promise 생성함수가 rejected되었을 때 반환
    • Promise.prototype.then() <- Promise 생성함수가 fulfilled되었을 때 반환
    • Promise.prototype.finally() <- fulfilled, rejected와 관계없이
  • Q) Promise.prototype.then 메소드는 무엇을 리턴하나요?

    • Promise.prototype.then 은 Promise를 리턴하고 resolve함수와 reject함수를 인수로 받는다.
  • Q) Promise.prototype.catch 메소드는 무엇을 리턴하나요?

    • Promise.prototype.catch 는 Promise를 리턴하고 error를 인수로 가진다.
  • Q) Promise의 세 가지 상태는 각각 무엇이며, 어떤 의미를 가지나요?

    • Pending(대기): fulfilled 또는 rejected 중 어느 것도 되지 않은 상태
    • fulfilled(이행): Promise 실행함수가 성공적으로 완료된 상태
    • rejected(거부): Promise 실행함수의 실행이 실패한 상태
  • Q) await 키워드 다음에 등장하는 함수 실행은 어떤 타입을 리턴할 경우에만 의미가 있나요?

    • Promise 타입을 리턴할 경우에만 의미가 있다.
  • Q. await 키워드를 사용할 경우, 어떤 값이 리턴되나요?

    • Promise가 fulfilled이면 promise를 reject이면 rejected value를 리턴한다.

출처 : 코드스테이츠

profile
끝까지 ... 가면 된다.

0개의 댓글