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. PHPのクラスの継承

  2. Windowsスクリプト

  3. CakePHP(2)

  4. やっぱりドットインストールは勉強にいい

  5. PostgreSQL JDBCドライバーの注意点

  6. MacでKHCoderを動かすなどについての愚痴

  7. ソフトウェアは進歩し続けなけりゃならんのか?

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