LoginSignup
28
23

More than 5 years have passed since last update.

image onloadをfor文で回す際の注意

Posted at

割りとjavaScriptでハマりがちな定番例かとは思いますが、
ご多分に漏れず僕もハマってしまいました。
for文の中に非同期処理を入れる際の落とし穴です。

例えば、Imageオブジェクトのonloadメソッドのような非同期処理を
for文の中に入れようとすると、

for(var i = 0; i < 5; i++){
    img[i] = new Image();
    img[i].onload = function(){
        console.log(i);
    }; 
    img[i].src = url;
}

とかって最初は書いちゃうかと思います。
これで、望まれる結果としてはimageのloadが完了した順に

3
4
2
1
5

とかって出力してほしいんですが、実際には

5
5
5
5
5

という結果が出力されます。

これは、console.logが出力している変数iが値そのものではなく、
あくまで参照値としてのiであるためです。
したがって、onloadが発火する際にはfor文が最後まで回りきっているため、全て5が出力されてしまいます。

これを解決するには、もうひとつ関数を作ってiを引数として渡してあげる必要があります。

すなわち、

for(var i = 0; i < 5; i++){
    img[i] = new Image();
    img[i].onload = finish(i);
    img[i].src = url;

    function finish(i){
        return function(){
            console.log(i);
        }
    }
}

とすることで、望むべき結果を得ることができます。

このfinish関数内のconsole.logは出力している変数iは、
参照値ではなく値そのものを出力しているためです。

28
23
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
23