TIL 73 asyncとwait


JavaScript async、await、および有用なPromise API
上のビデオに基づいて作られています.








// async & await
// clear style of using promise 

// 1. async
async function fetchUser() {
  // do network request in 10 secs ...
  return 'ellie';
}

const user = fetchUser();
user.then(console.log);
console.log(user);

// 2. await ✨
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(1000);
  return '🍎';
}

async function getBanana() {
  await delay(1000);
  return '🍌';
}

function pickFruits() {
  return getApple()
  .then(apple => {
    return getBanana()
    .then(banana => `${apple} + ${banana}`);
  });
}

async function pickFruits() {
  const applePromise = getApple();
  const bananaPromise = getBanana();
  const apple = await applePromise;
  const banana = await bananaPromise;
  return `${apple} + ${banana}`;
}

pickFruits().then(console.log);

// 3. useful Promise APIs
function pickAllFruits() {
  return Promise.all([getApple(), getBanana()])
  .then(fruits => fruits.join(' + '));
}
pickAllFruits().then(console.log);

function pickOnlyOne() {
  return Promise.race([getApple(), getBanana()]);
}
pickOnlyOne().then(console.log);

async & await

  • のプログラミングを継続すると、コードの可読性が低下する
  • API
  • は、「待機」Promiseを単純かつ同期的に動作させる
  • asyncとawaitは新しいものを追加するのではなく、既存のPromise上でより簡単なAPIを提供しています.これは文法糖と呼ばれています(Classもそうです).
  • なぜ非同期処理を行わなければならないのですか?

  • JSエンジンブロック({})内で同期運転(処理)コード
  • 非同期処理に時間がかかるコードがない場合、
  • という問題が発生する可能性があります.
    例えば、サーバがデータを受信してウェブページに出力するスキームは
  • である.
  • のデータの受信には10秒かかるが、非同期処理を行うと空データ
  • が出力される.
  • Promise情景劇:私はいつユーザーのデータを受け取るか分かりませんが、もしあなたがPromiseというオブジェクトがあれば、ここでThenというコールバック関数を登録すれば、ユーザーのデータを準備すれば、私はあなたにノートのコールバック関数
  • を呼びます.

    1. async


    1.1従来のアプローチ

    // 프로미스를 사용하면 반드시 resolve와 reject를 호출해야 함
    function fetchUser() {
      return new Promise((resolve, reject) => {
        // return `ellie`; // 프로미스 pending 상태
    		resolve(`ellie`); // 프로미스 fulfilled 상태
    		// reject(new Error(`error`)); // 프로미스 rejected 상태
      });
    }
    
    const user = fetchUser();
    // console.log(user);
    user.then(user => console.log(user));

    1.2 asyncの使用

  • asyncを使用すると、関数のコードブロックが自動的にPromiseに変換されます(素晴らしい!)
  • // 1. 함수 선언식
    async function fetchUser() {
      return `ellie`;
    }
    
    // 2. 함수 표현식
    const fetchUser = async function() {
      return `ellie`;
    };
    
    // 3. 화살표 함수
    const fetchUser = async () => {
      return `ellie`;
    };
    
    // fetchUser().then(data => console.log(data)); // 함수로 바로 호출
    const user = fetchUser(); // 변수에 할당해서 호출
    user.then(data => console.log(data));
    console.log(user);

    2. await


    2.1従来のアプローチ(Promise)

  • 召喚地獄が昇る.
  • function delay(ms) {
      return new Promise (resolve => setTimeout(resolve, ms));
    }
    
    function getApple() {
      return delay(1000)
      .then(() => `🍎`);
    }
    function getBanana() {
      return delay(1000)
      .then(() => `🍌`);
    }
    
    function pickFruits() {
      return getApple()
      .then(apple => {
        return getBanana().then(banana => `${apple} + ${banana}`);
      });
    }
    pickFruits().then(result => console.log(result));

    2.2 awaitの使用(エラー処理:try/catch文)

  • 待機async関数でのみ使用可能
  • GetAppleとGetBananaは互いに独立したコードであり、順次実行→低効率
  • function delay(ms) {
      return new Promise (resolve => setTimeout(resolve, ms));
    }
    
    async function getApple() {
      await delay(1000);
      // throw new Error(`error: apple`); // error 발생
      return `🍎`;
    }
    async function getBanana() {
      await delay(1000);
      // throw new Error(`error: banana`);
      return `🍌`;
    }
    
    async function pickFruits() {
      let apple = null;
      try {
        apple = await getApple();
      } catch(error) {
        console.log(error);
      }
      let banana = null;
      try {
        banana = await getBanana();
      } catch(error) {
        console.log(error);
      }
      return `${apple} + ${banana}`;
    }
    pickFruits().then(result => console.log(result));

    2.3並列処理待ち

    function delay(ms) {
      return new Promise (resolve => setTimeout(resolve, ms));
    }
    
    async function getApple() {
      await delay(1000);
      return `🍎`;
    }
    async function getBanana() {
      await delay(1000);
      return `🍌`;
    }
    
    // 방법 1: 무식한 코드
    async function pickFruits() {
      // 프로미스 객체는 선언 즉시 바로 실행됨
      // getApple과 getBanana는 병렬(독립적)로 실행됨
      const applePromise = getApple();
      const bananaPromise = getBanana();
      // 동기화
      const apple = await applePromise; 
      const banana = await bananaPromise;
      return `${apple} + ${banana}`;
    }
    pickFruits().then(result => console.log(result));
    
    // 방법 2: Promise APIs 사용
    function pickAllFruits() {
      return Promise.all([getApple(), getBanana()]).then(fruits => {
        return fruits.join(` + `);
      });
    	// return Promise.all([getApple(), getBanana()]);
    }
    pickAllFruits().then(console.log);
    
    // 번외: 비동기 처리중 먼저 리턴하는 녀석만 출력
    function pickOnlyOne() {
      return Promise.race([getApple(), getBanana()]);
    }
    pickOnlyOne().then(console.log);