JavascriptでPromise.allを使って複数の画像がロードされるまで待つ
Javascriptで画像をロードして扱う場合、ロードが完了するまで待たなければいけない場合があります。
例えば
画像要素.naturalWidth プロパティ(ピクセル単位の画像の幅)
画像要素.naturalHeight プロパティ(ピクセル単位の画像の高さ)
を取得したい場合は、画像がロードされるまで正しい値を取得することが出来ません。
画像が1つであれば簡単でonloadイベントを使って以下のように記述することが出来ます。
let img=new Image();
img.onload=function(){
//ロードが完了した時の処理;
}
img.onerror=function(e){
//ロードが失敗した時の処理;
}
img.src=url;
しかし、複数の画像をロードして扱う場合は、全てがロードされるまで待たなければいけません。
この場合、
Promise.all(反復可能オブジェクト).then(完了関数).catch(拒否関数)
を使用すると全ての画像のロードが完了(成功)した場合のみ処理を続けることが出来ます。
(例)複数画像のロードの完了を待つ
以下ソースコードは画像4つのロードの完了を待ってから、naturalWidthとnaturalHeightプロパティを使用しています。
<div id="image_list"></div>
<script>
let urls=['./imgs/0001s.jpg','./imgs/c001.jpg','./imgs/c001s.jpg','./imgs/c002.jpg'];
window.addEventListener('load',function(){
loadImages();
});
function loadImages(){
Promise.all(
urls.map(function(url){
return new Promise(function(resolve,reject){
let img=new Image();
img.onload=function(){resolve(img);}
img.onerror=function(e){reject(e);}
img.src=url;
});
})
).then(function(imgs){
//全ての画像ファイルがロード完了できた場合
let html ='<table class="tbl">';
html+='<tr><th>ファイル名</th><th>画像</th><th>幅</th><th>高さ</th></tr>';
imgs.forEach(function(img,i){
html+='<tr>';
html+=' <td>'+urls[i]+'</td>';
html+=' <td>';
html+=' <img style="width:auto;height:30px;" src="' +urls[i] + '"'+
' width="' + img.naturalWidth + '" height="' + img.naturalHeight + '">';
html+=' </td>';
html+=' <td>'+img.naturalWidth+'</td>';
html+=' <td>'+img.naturalHeight+'</td>';
html+='</tr>';
});
html+='</table>';
document.getElementById('image_list').innerHTML=html;
console.log('Finish');
}).catch(function(e){
//1つでも画像ファイルがロードできなければエラー
console.log('Error');
});
}
</script>
