Promiseを使用して複数のファイルを連続して読み込む[IE対応版]
JavaScriptの標準規格の「ECMAScript6」(2015年6月17日公開)の機能である「Promise」をInternet Explorerで使用して複数のファイルを同期のように連続して読み込むサンプルです。
Web Workerを使用した連続読み込みは「ファイルを同期・非同期で読み込む」(バイナリ用)をご覧ください。非同期を巧みに使用した読み込みは「Image.onloadを同期で読み込む」です。
Promise
PromiseオブジェクトはIEには搭載されていませんので、オープンソースのPolyfillライブラリ(ポリフィル)を使用します。PolyfillとはIEなどのブラウザで搭載されていない新機能をライブラリを使用して使用できるようにするものです。
今回、使用するのはMITライセンスの「native-promise-only」です。ファイルは「npo.src.js」で約8.7kbです。このファイルを「圧縮(minify)」すれば約3.4kbぐらいなので軽量です。
軽量だけは無く、JavaScriptの規格に沿って作成されているので「Edge/Chrome/Firefox」などのブラウザのPromiseオブジェクトと同様です。
※ブラウザにPromiseオブジェクトが既にある場合は、そちらを使用します。
ファイルを連続して読み込む 1
次のサンプルは複数の画像ファイルを連続して読み込みながら、ページ下部にcanvasを追加して読み込んだ画像を描画します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src ="npo.src.js"></script>
<script>
// 非同期で画像の読み込み
function getAsynchroImageData(file) {
return new Promise(function(resolve, reject) {
var image = new Image;
// イメージが読み込まれた
image.onload = function (){
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
ctx = canvas.getContext("2d");
ctx.drawImage(image,0,0);
resolve(ctx.getImageData(0, 0, image.width, image.height));
}
// イメージが読み込めない
image.onerror = function (){
reject(Error('この画像は読み込めません。\n' + file.name));
};
image.src = file.data;
});
}
// 非同期でファイルを読み込む
function getAsynchroFile(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function (event) {
resolve({'data':reader.result,'name':file.name});
}
reader.onerror = function (event) {
reject('ファイルの読み込みに失敗しました');
}
reader.readAsDataURL(file);
});
}
// ドラッグオーバー
function onDragOver(event){
event.preventDefault();
}
// ドロップ
function onDrop(event){
onAddFile(event);
event.preventDefault();
}
// ユーザーによりファイルが追加された
function onAddFile(event) {
var files;
if(event.target.files){
files = event.target.files;
}else{
files = event.dataTransfer.files;
}
// 連続してファイルを読み込む
for(var i=0;i<files.length;i++){
// ファイルの読み込み
getAsynchroFile(files[i]).then(function(file){
// 画像の読み込み
getAsynchroImageData(file).then(function(imagedata){
// canvasを生成してImageDataを描画する
var canvas = document.createElement('canvas');
canvas.width = imagedata.width;
canvas.height = imagedata.height;
ctx = canvas.getContext("2d");
ctx.putImageData(imagedata,0,0);
document.body.appendChild(canvas);
// エラー(画像の読み込み失敗)
}).catch(function(err){
alert(err);
});
// エラー(ファイルの読み込み失敗)
}).catch(function(err){
alert(err);
});
}
}
</script>
</head>
<body ondrop="onDrop(event);" ondragover="onDragOver(event);">
<h4>画像の読み込み (複数可能)</h4>
<p></p>
<input type="file" id="inputfile" accept="image/jpeg,image/png,image/gif,image/bmp" multiple onchange="onAddFile(event);">
<p></p>
</body>
</html>
ファイルを連続して読み込む 2
今度は「1」のサンプルを改良したものです。結果は同じですのでお好きな方を使用してください。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src ="npo.src.js"></script>
<script>
// 非同期で画像の読み込み
function getAsynchroImageData(file) {
return new Promise(function(resolve, reject) {
var image = new Image;
// イメージが読み込まれた
image.onload = function (){
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
ctx = canvas.getContext("2d");
ctx.drawImage(image,0,0);
resolve(ctx.getImageData(0, 0, image.width, image.height));
}
// イメージが読み込めない
image.onerror = function (){
reject(Error('この画像は読み込めません。\n' + file.name));
};
image.src = file.data;
});
}
// 非同期でファイルを読み込む
function getAsynchroFile(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function (event) {
resolve(getAsynchroImageData({'data':reader.result,'name':file.name}));
}
reader.onerror = function (event) {
reject('ファイルの読み込みに失敗しました');
}
reader.readAsDataURL(file);
});
}
// ドラッグオーバー
function onDragOver(event){
event.preventDefault();
}
// ドロップ
function onDrop(event){
onAddFile(event);
event.preventDefault();
}
// ユーザーによりファイルが追加された
function onAddFile(event) {
var files;
if(event.target.files){
files = event.target.files;
}else{
files = event.dataTransfer.files;
}
for(var i=0;i<files.length;i++){
// ファイル(画像)の読み込み
getAsynchroFile(files[i]).then(function(imagedata){
// canvasを生成してImageDataを描画する
var canvas = document.createElement('canvas');
canvas.width = imagedata.width;
canvas.height = imagedata.height;
ctx = canvas.getContext("2d");
ctx.putImageData(imagedata,0,0);
document.body.appendChild(canvas);
// 読み込み失敗
}).catch(function(err){
alert(err);
});
}
}
</script>
</head>
<body ondrop="onDrop(event);" ondragover="onDragOver(event);">
<h4>画像の読み込み</h4>
<p></p>
<input type="file" id="inputfile" accept="image/jpeg,image/png,image/gif,image/bmp" multiple onchange="onAddFile(event);">
<p></p>
</body>
</html>
Promiseに関しては次のリンク先で詳細を確認して下さい。
Promise関連リンク(外部)
JavaScript Promiseの本
JavaScript Promises
Promise (MDN)
Promise クラスについて
今更だけどPromise入門
関連記事
| 前の記事: | JavaScriptの品質チェックと厳格なコーディングには「JSLint」と「use strict」を使う[ECMAScript5以降] |
| 次の記事: | JavaScriptでタイマーを使用する[setTimeout/setInterval] |
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









