ITで遊ぶ

javascriptでfetchを使うことはよく考えたほうがいい

ほぼ一日、無駄にしました。

Javascriptでサーバー側のファイルを読むこむ時、「fetchでできる」とうれしそうに書いている例が何百とある。

が、よく考えてみてほしい。実用的なプログラムを書く場合、以下のようにすることを期待しませんか?

fetch(url) 
  .then(response => {
    return response.text();  
  })
  .then(data => {
    const allrecods = data  //みなさんここをconsole.log(data)でごまかす!!!
  })
  .catch(error => {
    console.error(error);  
  });

records = allrecords.split('¥n')

これできないんですよ。
fetch全体が終了したと見えても、recordsに値は入っていません。
そして戻ってくるallrecordsはstringではなく、promise objectというやっかいなものに化けます。
どうやっても化けます。
解決するためには、さらにコールバックルーチンを用意して同期を取らないといけません。

時々、promiseとawaitを別物だと思いこんでいる人がいますが、awaitの中身はpromiseですからね。

みーんなが、console.logでデータが出たからOKとして記事を終了するからスマートに見えるんです。
だから、多くの人が孫引きしているサンプルコードってアテにならないんです。

で、非同期とオブジェクトに苦しむくらいなら従来のxmlhttprequestで

const xhr = new XMLHttpRequest();
xhr.open("GET", some url, false);
xhr.send();
if (xhr.status == 200){
   const alltext = xhr.responseText
   records = alltext.split('¥n')  // records must be global variable.
} else{
   records = []
}

と、同期型で書く。変数recordsはグローバル変数にしないとこのifを抜けた途端に消えます。
確かにfetchのほうが機能は多いし新しいけど、イベントハンドラーの中ですべてを済ませることが暗黙の前提なのではないでしょうか。

そしてXMLHttpRequest使ったからといって、別にcallbackの嵐にもならないし、書き方も簡潔だと思うんですけどね。

関連記事

  1. 簡単なCSSフレームワーク milligram

  2. CakePHP(1)

  3. 製品を作るおじさんの独り言

  4. PHPバッチ

  5. 多くのテキストファイルをWordPressの投稿に書き込む

  6. Arduinoで脈拍を測る

  7. WooCommerceからB2Webへ(2)

  8. MPASMがなくなった

記事をプリント