Hatena::Groupptech

ぷちてく RSSフィード

Archive
 
ProfileProfile

2017-03-01

ネストした同イベントハンドラ代入式

05:15

単純に外側のハンドラ内で再度イベントが発生、内側のハンドラが呼ばれる、という構造だった。

記事あげてから、id:a-kuma3 さんがコメントしてくれて気付いた。

2017/03/02 08:51 by a-kuma3

ありがたい。

ハマりどころ

外側のハンドラの最後で readAsText() 呼んでるところで load 発生するの見落としてた。

FileReaderreadAs*() 完了時全般で load 発生するの、自分でMDNのリンク貼ったのに。

  • 眠気を感じる時や疲労時はコードの運転を控えましょう
  • 余裕を持ってコードの「かもしれない運転」を行いましょう

というのがぼくからの言葉です。長いので謎解きは新しい記事にした。

ではハマってる様子をどうぞ。


混乱避け・拡張性とか考えて普段 receiver.addEventListener() しか使わないのだけど、receiver.onload = ... が理解超えた挙動する。詳しい人教えて欲しい。JavaScriptの話です。

via

readerFileReader

現在のドキュメントを文字コード自動判定で読み直す - Hatena::Let

これ outer -> inner 走るんだけどマジか…

reader.onload = function() {
  // outer ...
  reader.onload = function() {
    // inner ...
  };
};
no title

上みたいな感じで onload = function(){} がネストしてて両方順番に走る。

id:unarist さんが書いたこのリビジョン。

console.log 入れて確かめた。

  reader.onload = function() {
    console.log('outer');
    //  ...
    reader.onload = function() {
      console.log('inner');
      //  ...
    };
  };
// -> outer
// -> inner

アイエエエ!?」「ネスト!?ネストナンデ!?」

うーん、+= みたいになるの? C#delegate w/ 演算子オーバーライドみたいな。

再現失敗

手っ取り早くXHRでテスト書いたところ、理解は出来るけど再現出来なかった。

xhr = new XMHttpRequest();
xhr.open('GET', location.href);
xhr.onload = () => {
  console.log('outer');
  xhr.onload = () => { console.log('inner'); };
};
xhr.send();
// -> outer

これはこれで一瞬ビックリだけど、 onload 入った時に発火終わってるって考えると普通に見える。

xhr = new XMLHttpRequest();
xhr.open('GET', location.href);
xhr.addEventListener('load', () => {
  console.log('outer');
  xhr.addEventListener('load', () => { console.log('inner'); });
});
xhr.send();
// -> outer

addEventListener() も同じ。

FileReader が特別なようには見えないんだけどなー。

「オメーのコードが間違ってんだよハゲ!」とか、「テメーの目はフシアナか?どう読んでんだよアアン!?」とか、「コンコンコン、もしもーし?脳みそ入ってますかー?」みたいなのも助かります。


APPENDIX

環境
$ apt-cache policy chromium-browser
chromium-browser:                             
  Installed: 56.0.2924.76-0ubuntu0.16.04.1268 
  Candidate: 56.0.2924.76-0ubuntu0.16.04.1268 
Chromium56.0.2924.76 (Developer Build) Built on Ubuntu , running on Ubuntu 16.04 (32-bit)
Revision314da7cc1e56fc9fa9271bac2b029922feb4b6f2
OSLinux
JavaScriptV8 5.6.326.42
Flash24.0.0.221 /usr/lib/adobe-flashplugin/libpepflashplayer.so
User AgentMozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/56.0.2924.76 Safari/537.36
Command Line/usr/lib/chromium-browser/chromium-browser --ppapi-flash-path=/usr/lib/adobe-flashplugin/libpepflashplayer.so --ppapi-flash-version=24.0.0.221 --enable-pinch --flag-switches-begin --overscroll-history-navigation=0 --disable-smooth-scrolling --disable-features=CredentialManagementAPI,MaterialDesignHistory --flag-switches-end
Executable Path/usr/lib/chromium-browser/chromium-browser
Profile Path/home/noro/.config/chromium/Default

> chrome://version/

フラットな時

普通のやつの挙動です。

xhr = new XMLHttpRequest();
xhr.open('GET', location.href);
xhr.onload = () => console.log('#1');
xhr.onload = () => console.log('#2');
xhr.send();
// -> #2

最後に代入したやつが出る。そりゃそうですね。

xhr = new XMLHttpRequest();
xhr.open('GET', location.href);
xhr.addEventListener('load', () => console.log('#1'));
xhr.addEventListener('load', () => console.log('#2'));
xhr.send();
// -> #1
// -> #2

くっつけただけ全部出る。そりゃそうですね。

a-kuma3a-kuma32017/03/02 08:51ハンドラの中で、もう一度 発火しているから。

const reader = new FileReader();
reader.onload = function() { <-- (*1)
...
reader.onload = function() { <-- (*2)
...
};
reader.readAsText(xhr.response, enc); (*2)
};
reader.readAsArrayBuffer(xhr.response); (*1)

noromanbanoromanba2017/03/03 03:45なるほど!

トラックバック - http://ptech.g.hatena.ne.jp/noromanba/20170301