ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Promise & Async, Await
    개발/Javascript 2022. 6. 6. 10:39

    *복습 자료라서 뻔한 내용은 생략

     

     

    Summary.

     

    1. A Promise is an object representing the eventual completion or failure of an asynchronous operation

     

    2. A Promise is a proxy for a value not necessarily known when the promise is created

        + instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future

        + 3가지 state: pending, fulfilled, rejected

        + When either of these options happens, the associated handlers queued up by a promise's then method are called.

        + then(), catch() 함수 둘 다 Promise를 return 하므로 Chaining 가능

        + then() 함수에 Promise 반환하는 callback 함수가 없으면 다음 Chain으로 넘어감 -> 따라서 catch() 함수를 마지막에만 둬도 동작함. 만약 즉시 처리가 필요하면 then() 함수의 두번째 인자로 넣어두면 됨

     

    3. 즉, Promise 생성 시 이미 async 함수는 실행되고, 결과가 settled (resolved or rejected) 됐을 때는 queued up 된 handler가 바로 실행됨

        + then() 함수로 handler 등록시키는데, 그 전에 settled 돼있을 수도 있고 안돼있을 수도 있음.  queue 이므로

       

    4. Static Method인 Promise.resolve() 와 Promise.reject() 는 주어진 값과 함께 Promise를 return 하는 함수

        + 아래와 같은 방식으로 Promise 정의 및 생성함 (setTimeout 대신 다른 async function을 수행하는 식)

        + resolve, reject 를 인수로 갖는 function 정의해서 new Promise(Foo) 처럼 Promise 생성하고, then으로 이어서 동작시키면 됨)

    let myFirstPromise = new Promise((resolve, reject) => {
      // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
      // In this example, we use setTimeout(...) to simulate async code.
      // In reality, you will probably be using something like XHR or an HTML5 API.
      setTimeout( function() {
        resolve("Success!")  // Yay! Everything went well!
      }, 250)
    })
    
    myFirstPromise.then((successMessage) => {
      // successMessage is whatever we passed in the resolve(...) function above.
      // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
      console.log("Yay! " + successMessage)
    });

     

    5.   Promise 인스턴스 함수인 then, catch는 Promise Constructor에 넘겨주는 함수와는 다르게 동작함

        + then/catch는 항상 Promise를 return 함

        + 값을 return 할 경우, Promise의 값을 해당 값으로 설정해줌 (return 안할 경우 undefined로 설정됨)

        + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#return_value

        + 만약 callback handler 이 주어지지 않으면 그냥 다음으로 넘어감

        + 다음이 then() 함수 syntax

    p.then(onFulfilled[, onRejected]);
    
    p.then(value => {
      // fulfillment
    }, reason => {
      // rejection
    });

     

    6. Promise Chain을 더 깔끔하게 작성하기 위해 나온 키워드가 Async, Await (ECMAScript 2017)

        + Await은 Async 함수 내에서만 사용 가능

        + Async Function Declaration 과 Expression 둘 다 가능

        + Async Function도 Promise 반환 (즉, 이 함수 자체도 Await 대상일 수 있음. 실제로 그렇게 다룰 듯. 물론 후속처리할 것 없으면 await 안해도 됨)

    function foo() {
       return Promise.resolve(1)
    }
    
    // same as above
    async function foo() {
       return 1
    }

     

     

     

    7. Promise.all, Promise.allSettled, Promise.any 처럼 Parallel 한 실행법도 있음 (Composition)

        + reduce 함수 이용도 가능 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#composition

     

    8. Promise callbacks are handled as a Microtask whereas setTimeout() callbacks are handled as Task queues.

    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
    
    wait(0).then(() => console.log(4));
    Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
    console.log(1); // 1, 2, 3, 4

     

    9. Callback Hell -> Promise -> Async/Await 변화

    doSomething(function(result) {
      doSomethingElse(result, function(newResult) {
        doThirdThing(newResult, function(finalResult) {
          console.log('Got the final result: ' + finalResult);
        }, failureCallback);
      }, failureCallback);
    }, failureCallback);
    doSomething()
    .then(function(result) {
      return doSomethingElse(result);
    })
    .then(function(newResult) {
      return doThirdThing(newResult);
    })
    .then(function(finalResult) {
      console.log('Got the final result: ' + finalResult);
    })
    .catch(failureCallback);
    
    // catch(failureCallback) 은 then(null, failureCallback)과 같음 (원래 then(successFunc, failFunc))
    doSomething()
    .then(result => doSomethingElse(result))
    .then(newResult => doThirdThing(newResult))
    .then(finalResult => {
      console.log(`Got the final result: ${finalResult}`);
    })
    .catch(failureCallback);
    try {
      const result = syncDoSomething();
      const newResult = syncDoSomethingElse(result);
      const finalResult = syncDoThirdThing(newResult);
      console.log(`Got the final result: ${finalResult}`);
    } catch(error) {
      failureCallback(error);
    }
    // ECMAScript 2017
    async function foo() {
      try {
        const result = await doSomething();
        const newResult = await doSomethingElse(result);
        const finalResult = await doThirdThing(newResult);
        console.log(`Got the final result: ${finalResult}`);
      } catch(error) {
        failureCallback(error);
      }
    }

     

    Additional.

    1. incumbent realm tracking 란?

     

    2. unhandledrejection은 reject 발생 시 자동으로 global (ex) window or Worker)로 전달되는 RejectionEvent

        ex) node.js - process.on("unhandledRejection", function(reason, promise){});

     

    3. Nesting 잘 활용하면 Error 세심하게 관리 가능

        + https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#nesting

    doSomethingCritical()
    .then(result => doSomethingOptional(result)
      .then(optionalResult => doSomethingExtraNice(optionalResult))
      .catch(e => {})) // Ignore if optional stuff fails; proceed.
    .then(() => moreCriticalStuff())
    .catch(e => console.error("Critical failure: " + e.message));

     

    Reference.

    '개발 > Javascript' 카테고리의 다른 글

    History (ECMAScript)  (0) 2022.06.06
    Runtime / Execution Stack / Task Queue  (0) 2022.06.06
    Module System  (0) 2022.06.05
    Prototype Chain  (0) 2022.06.05
    Memory Management  (0) 2022.06.05
Designed by Tistory.