TIL 24. JS Promiseとasync&await


JavaScriptのPromiseとasync&awaitの概念について説明します.本明細書は、MDNおよび板橋隊長に基づく.

Promise


“A promise is an object that may produce a single value some time in the future”
プロセスはJavaScriptの非同期処理に使用されるオブジェクトです.プロミスは私たちがまだ知らない未来の価格を処理することができます.
Promiseを使用すると、callback関数を使用して、どの結果を満たすか、どの結果を拒否するかによって、異なる処理を行うことができます.本質的に、Promiseはコールバックをパラメータ値として通常の関数に入れるのではなく、戻りオブジェクトです.
非同期関数から結果を同期して返すことができます.

Guarantees

thenメソッドに入るコールバック関数はjavascriptイベントループで処理が完了するまで絶対に呼び出されません.
Promiseが示す非同期実行が成功または失敗した後でも、コールバック関数が呼び出されます.

Promiseの3つのステップ

  • 保留(代替):非同期処理ロジックがまだ完了していません
  • Fulfilled(履行済み):非同期処理を完了し、プロセスから結果値
  • を返す
  • Rejected(失敗):非同期処理失敗またはエラーステータス
  • 例:お母さんのランダムな気持ちで携帯電話を受信したり、受信できないPromiseを受信したり
    const isMomHappy = Math.random();
    
    // Promise
    const willIGetNewPhone = new Promise(function (resolve, reject) {
      if (isMomHappy > 0.3) {
        const phone = {
          brand: "Samsung",
          color: "black",
        };
        // 3초 setTimeout
        setTimeout(() => resolve(phone), 3000); // if fulfilled
      } else {
        const reason = new Error("mom is not happy");
        reject(reason); // if rejected
      }
      
      // 동기적인 코드
      console.log(willIGetNewPhone) // Promise{<pending>}
      // setTimeout이지만 3초가 되기 이전이므로 pending.
      setTimeout(() => console.log(willIGetNewPhone), 1000); // Promise{<pending>}
      setTimeout(() => console.log(willIGetNewPhone), 2000); // Promise{<pending>}
      
      // 4초 후 참조하는 Promise : 여기선 슬프게도 rejected라는 결과가 나왔다.
      setTimeout(() => console.log(willIGetNewPhone), 4000);
    // Promise {<rejected> Error: mom is not happy}
    しかし、上記のコードの欠点は、毎回settimeoutに設定された時間を確認することである.また、settimeoutを使用しているので、どれくらいの時間がかかるか予測できますが、サーバからデータを受信する場合、どうすればいいのでしょうか.データを受け取った後、すぐにコールバック関数を実行する方法はありますか?

    方法

    // then 메서드를 이용해서 pending이 끝난 후에 주어진 callback함수를 실행한다.
    willIGetNewPhone.then((value) => console.log(value));

    Promiseのエラー処理方法

    // UnhandledPromiseRejectionWarning: Error: mom is not happy
    上記のコードではrejectedの場合、エラー処理は行われず、残りのすべてのコードが停止します.
    Promiseでエラーを処理する典型的な方法は.catchです.これにより、コードを停止させるのではなく、エラーを安定的に処理することができます.
    willIGetNewPhone
      .then((value) => console.log(value))
      .catch((error) => console.log(error));

    onfulfilled


    onfulledという隠し属性があります.これは、サーバ側がリクエストを承認しvalueを取得したデータです.Javascriptエンジンでは,この属性はWeb APIによって埋め込まれるのを待つと考えられる.
    そして、onfulledが満たされると、then()にコールバックとして送信される関数が実行される.
    onfulledは非表示のプロパティです.だから近づくことはできますが、変えることはできません.

    結局コールバックだけが知っていた。


    Only the function responsible for creating the promise will have knowledge of the promise status, or access to resolve or reject.

    Errorオブジェクト


    When I reject() with a value, I always pass an Error object. Generally I want two possible resolution states: the normal happy path, or an exception — anything that stops the normal happy path from happening. Passing an Error object makes that explicit.

    async & await


    The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.
    asyncとawaitはJavaScript非同期処理モードで最近出現した構文である.従来の非同期処理方法のコールバック関数とプロセスの欠点を補い、開発者が読み取り可能なコードを作成するのに役立ちます.

    async&awaitの使い方

    async function 함수명() {
      await 비동기_처리_메서드_명();
    }
    
    まず関数の前にasyncという定語をつけます.asyncキーワードはPromiseオブジェクトの作成を許可します.そして関数の内部論理でHTTP通信を行う非同期処理コードにwaitを付ける.ここで注意すべき点は、awaitの意図に従って操作するには、非同期処理方法がpromisオブジェクトを返さなければならないことです.
    通常、awaitの非同期処理コードはAPI呼び出し関数であり、Axiosなどのプロセスを返します.

    エラー処理:try&catch


    プロミスでエラーを処理するために.catch()を使用するように、asyncはcatch{}を使用することができます.
    catchは、ネットワーク通信エラーや単純なタイプのエラーなど、一般的なエラーをキャプチャします.検出されたエラーはerrorオブジェクトに含まれるため、エラーのタイプに応じてエラーコードを処理できます.
    async function logTodoTitle() {
      try {
        var user = await fetchUser();
        if (user.id === 1) {
          var todo = await fetchTodo();
          console.log(todo.title); // delectus aut autem
        }
      } catch (error) {
        console.log(error);
      }
    }