🚀

【JavaScript】【初級者脱却】非同期通信について#2 Promiseとは

に公開

前書

前回、async関数の戻り値はPromiseだと書きました。
では、Promiseとは何か。

Promiseとは

Promiseとは、非同期処理の『結果』です。
『結果』なので、処理の成否に関わらず必ず完了している必要があります。

Promiseの状態の変遷

状態 意味
pending 未解決
resolveed 解決
rejected 失敗

Pending(未解決)

処理の結果が返せる状態になる前は、Pendingの状態になります。
この状態はまだ結果を返せません。

Resolved(解決)

正常に処理が完了した場合は、その結果としてResolvedを戻り値で返します。  
Promiseのメソッドチェーンで記述した場合、Resolvedが返ったあとはthenの処理が実行されます。  
async-await、try-catchで記述した場合は、tryの後続の処理が実行されます。

Rejected(失敗)

正常に処理が完了しなかった場合、その結果としてRejectedを戻り値で返します。

Promiseのメソッドチェーンで記述した場合、Rejectedが返ったあとはcatchの処理が実行されます。  
async-await、try-catchで記述した場合は、catchの処理が実行されます。

非同期処理の実装と結果例

1. シンプルな非同期処理

function samplePromise1 () {
  console.log('first');

  setTimeout(() => {
    console.log('second');
  }, 300);

  console.log('third');
};

samplePromise1();

// first
// third
// second

2. async-awaitを使った書き方

async function samplePromise2 () {
  try {
    console.log('first');
    await returnPromise();
    console.log('third');
  } catch (error) {
    return;
  }
};

function returnPromise () {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(console.log('second'));
    }, 100);
  });
};

samplePromise2();

// firsd
// second
// third

3. 非同期処理でPromiseがrejectを返した場合

async function samplePromise3 () {
  try {
    console.log('first');
    await returnPromise();
    console.log('third');
  } catch (error) {
    console.log('error');
  }
};

function returnPromise () {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(console.log('second'));
    }, 100);
  });
};

samplePromise3();

// firsd
// second
// error

Promiseはawaitで受け取る

return Promiseはその記述の通り、Promiseを返します。  
Promise内の処理の完了を待って受け取りたい場合、awaitで受け取る必要があります。
awaitで受け取らないと、結果を待つことなくPromiseオブジェクトをそのまま受け取ってしまいます。

1. 非同期処理のPromiseをawaitで受け取った場合

async function samplePromise4 () {
  try {
    console.log('first');
    console.log(await returnPromise());
    console.log('third');
  } catch (error) {
    return;
  }
};

async function returnPromise () {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('second');
      resolve(1);
    }, 100);
  });
};

samplePromise4();

// firsd
// second
// 1
// third

2. 非同期処理のPromiseをawaitで受け取らなかった場合

// awaitで受け取らなかった場合
async function samplePromise5 () {
  try {
    console.log('first');
    console.log(returnPromise());
    console.log('third');
  } catch (error) {
    return;
  }
};

async function returnPromise () {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('second');
      resolve(1);
    }, 100);
  });
};

samplePromise5();

// first
// Promise {}
// third
// second
// 処理の完了を待たない上に、returnPromise()の戻り値はpending状態のPromiseオブジェクトになる

次回

じゃあ結局非同期処理ってなんやねん

連載リンク

非同期通信について
#1 async関数の戻り値
#2 Promiseとは
#3 同期・非同期処理のフロー図解
#4

Discussion