hysryt / wiki

https://hysryt.github.io/wiki/
0 stars 0 forks source link

Promise #57

Open hysryt opened 6 years ago

hysryt commented 6 years ago

Promise は以下のような、ボトルネックが発生する処理とともに使われる。

JavaScript ではこれらの処理(関数呼び出し)に差し掛かった場合、待ち状態にはならず、次の処理に移行する。ではどのようにネットワーク通信等の応答を受け取るかというと、 JavaScript ではイベントという形で受け取る。関数呼び出しの際に応答用の関数(コールバック)を指定し、処理が終わったらそのコールバックを実行してもらうことでイベントを実現する。このようなイベント主体の処理のことをイベント駆動と言ったりする。

イベント駆動の優れているところは、待ち状態にならないこと。 イベントが呼ばれるまでの間、他の処理を行うことができる。 待ち状態にならないことでリソースを無駄にしなくて済む。 この「待ち状態にならないこと」をノンブロッキングとか言ったりする。

Promise の利点には以下のようなものがある。

視認性について。 直列処理は then を使っていかにも直列処理っぽく書ける。 さらに async/await を使えば通常の処理構文のように書くこともできる。

汎用性について。 Promise 以前の方法ではインターフェースが実装者に委ねられていたため使用する側はドキュメントに目を通す必要があった。 しかし Promise が導入されたことによってコールバック周りが仕様化され、実装者による差異がなくなり、同じ使用感を保つことができるようになった。

await について。 await はもともと Promise を基にした機能のため、従来の方法には使用できない。 かなり強力な機能なのでこれが使えるのは大きなメリットになる。

Promise がなくても不便になるというだけで、どうしようもないということはないが、あれば上記のようなメリットを享受できる。

たとえ Promise を使ったとしてもコールバックをなくすことはできない。 コールバックを無くしたい場合は async/await を使用する。

hysryt commented 6 years ago

Promise なし

function getData(callback) {
  setTimeout(() => {
    callback(10);
  }, 5000);
}

getData((data) => {
  console.log(data);
});

複数回getData() を順次実行させたい時、連結させればさせるほどネストが必要になる。

getData((data) => {
  console.log(data);
  getData((data) => {
    console.log(data);
    getData((data) => {
      console.log(data);
    });
  });
});

Promise あり

function getData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(10);
    }, 5000);
  });
}

getData().then((data) => {
  console.log(data);
});

複数回getData() を順次実行させたい時も簡潔に書ける。

getData().then((data) => {
  console.log(data);
  return getData();

}).then((data) => {
  console.log(data);
  return getData();

}).then((data) => {
  console.log(data);
  return getData();
});

Promise + await

await は Promise オブジェクトまたは async function に対して使うことができる。

// ここは上と同じ
// Promise を返すので await が使用できる
function getData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(10);
    }, 5000);
  });
}

const data = await getData();
console.log(data);

Promise だけの時よりさらに簡単に書ける。

let data = await getData();
console.log(data);

data = await getData();
console.log(data);

data = await getData();
console.log(data);