See the Elephant

1992生まれのプログラマが書くエンジニアブログ

fetch apiをあらためて

fetch

fetchを雰囲気でしか理解できていないので学んでいこう

mdn fetch概説

fetchはjsのAPIであり,リクエストやレスポンスといったHTTPのパイプラインを構成する要素を操作できるようになる.
またfetch() メソッドを利用することで、非同期のネットワーク通信を簡単にわかりやすく記述できるようになります。

うむ, productionコードでもfetchが登場する. XMLHttpRequestとの違いはなんだろう

XMLHttpRequest

XMLHttpRequest は、クライアントとサーバーの間でデータを伝送するための機能をクライアント側で提供する API です。ページ全体を再読み込みすることなく、URL からデータを読み出す簡単な方法を提供します。この API によって、ユーザの作業を中断させることなく Web ページの一部を更新することができます。 XMLHttpRequest は AJAX プログラミングで多く使用されます。

これはfetchも同じそう. apiのメソッドや, 使われ方見た感じでは xhrオブジェクトを生成して, オブジェクトに値をバインドしていき http reqパラメタを作るような感じになるっぽい.

https://qiita.com/sirone/items/412b2a171dccb11e1bb6

var xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://{送信先URL}/post.php', false );
// POST 送信の場合は Content-Type は固定.
xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
//
xhr.send( 'hoge=piyo&moge=fuga' );

fetch apiを使うことでオブジェクトの定義を行わずにhttp reqが生成できる

var myImage = document.querySelector('img');

fetch('flowers.jpg').then(function(response) {
  return response.blob();
}).then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

これはネットワークごしに画像を取得して <img> 要素に挿入するスクリプトである. 第一引数は取得したいリソースへのパスであり, 戻り値はResponseオブジェクトを獲得できるプロミスオブジェクトを返す.

fetchで取得したプロミスオブジェクトは function(response) のresponseに渡されてcallback functionで利用できる.

promiseオブジェクトってなんじゃい, ということで調べる.

promise

promiseとは

Promiseは非同期処理の最終的な完了もしくは失敗を表すオブジェクトです。要するに、Promiseはコールバックを関数に渡すかわりにコールバックを付属させるリターンされたオブジェクトです。
// 成功時にsuccessCallback, 失敗時にfailureCallbackが呼ばれる
doSomething().then(successCallback, failureCallback);

promiseを利用することでdoSomethingの処理が終わり, その成功/失敗状態に応じて次に実行するcallback関数を切り替えてくれる.

一般的なニーズとしては、複数の非同期処理を順番に実行し、前の処理の結果を次の処理で使うというものがあります。これはPromiseチェーンを作成することで行えます。

さあ魔法の時間です。 then 関数は元のPromiseとは別の新しいPromiseを返します。
基本的に、それぞれの Promise はチェーン(連鎖)させた別の非同期処理の完了を表します。
Promise は doSomething() の完了を表すだけではなく、渡した successCallback もしくは failureCallback の完了も表し、これらのコールバックはPromiseを返す別の非同期関数であっても構いません。
これまで、複数の非同期処理を順番に実行するには、昔ながらのコールバックの悲運のピラミッドを作る必要がありました。
近代的な関数を使えば、その代わりに戻り値の Promise にコールバックを付加して Promise チェーンとして記述できます。
//従来
doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Got the final result: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);

// promise
doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) { // doSomethingElse(result)の成功時実行結果
  return doThirdThing(newResult);
})
.then(function(finalResult) { // doThirdThing(newResult)の成功時実行結果
  console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback); // promiseが失敗した時の処理

promiseを使うことで非同期処理のチェーンを簡潔に記述できる

fetchのサンプルコードを読んで見る

var myImage = document.querySelector('img');

fetch('flowers.jpg').then(function(response) {
  return response.blob();
}).then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

ここまで調べて見ると,

  1. fetchメソッドで'flowers.jpg'にxhr get request
  2. responseオブジェクトがpromiseで返却
  3. response.blobでrequestストリーム全文読み込みを行いblobをpromiseで返却
  4. blobからURLを取得し, myImageに設定

promiseとfetchを組み合わせることでxhr requestがかなりいい感じで記述されていることがわかった 今日はここまで