見出し画像

非同期処理を考える - Callback。

JavaScriptで非同期処理を考える時によく出てくることばとして"callback"という言葉が出てきます。

callBack関数は高階関数の中で使われ、

setTimeout(function() { console.log('Hello!'); }, 2000);

setTimeout()がよく使われます。この場合は2000ms(2秒)後に
function() { console.log('Hello!');}
が実行され"Hello!"と出力されます。

出力が非同期的におき、setTimeout()はコールバックを使う代表的なものとなっています。

そこで

例えば連続で使うと

setTimeout(() => {
  console.log('1秒経ちました');
  setTimeout(() => {
    console.log('2秒経ちました');
    setTimeout(() => {
      console.log('3秒経ちました');
      setTimeout(() => {
        console.log('4秒経ちました');
      }, 1000);
    }, 1000);
  }, 1000);
}, 1000);

ネストが深くなりスッキリしません。コードの可読性・保守性・再利用性を下げ、このようになることをコールバック地獄などと表現する場合があります。

Promise

これをスッキリする方法ですが、Promiseを使うと、

const wait = function (seconds) {
  return new Promise(function (resolve) {
    setTimeout(resolve, seconds * 1000);
  });
};


wait(1)
  .then(() => {
    console.log('1秒経ちました');
    return wait(1);
  })
  .then(() => {
    console.log('2秒経ちました');
    return wait(1);
  })
  .then(() => {
    console.log('3秒経ちました');
    return wait(1);
  })
  .then(() => console.log('4秒経ちました'));


async/await

async/awaitを使うことでpromiseを使いながらではありますがスッキリと書くことができるようになります。

function resolveAfter2Seconds() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  const result = await resolveAfter2Seconds();
  console.log(result);
  // Expected output: "resolved"
}

asyncCall();

出力は

> "calling"
> "resolved"


これを修正して〜秒後というふうに連続で出してみます。

function resolveAfter2Seconds(sec) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('resolved');
    }, sec*1000);
  });
}

async function asyncCall() {
  console.log('calling');

  for (let i=1;i<4;i++){
      let result = await resolveAfter2Seconds(i);
      console.log(`${i}秒たちました`);
  }

}

asyncCall();

実行して出力してみます。

> "calling"
> "1秒たちました"
> "2秒たちました"
> "3秒たちました"
> "4秒たちました"

うまくいきました。

この記事が気に入ったらサポートをしてみませんか?