データのダウンロード進行状況の追跡と中断:JavaScriptにおける完全ガイド
データのダウンロードを行う際、特に大きなファイルを扱う場合、進行状況を追跡することは非常に重要です。進行状況を監視し、ユーザーにフィードバックを提供することで、より良いユーザーエクスペリエンスを実現できます。この記事では、JavaScriptを使用してデータのダウンロード進行状況を追跡する方法と、それを中断する方法について詳しく説明します。
1. Fetch APIによるデータのダウンロード
まず、データのダウンロードを行うための基本的な方法として、fetch()を使用します。fetch()は、HTTPリクエストを非同期で行うための関数で、Promiseベースで動作します。データをダウンロードする際、fetch()は通常、レスポンスのストリームを返します。これを利用して進行状況を追跡できます。
基本的な使用方法
javascriptfetch('https://example.com/largefile')
.then(response => {
// レスポンスが正常でない場合はエラーを投げる
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.body.getReader();
})
.then(reader => {
// データの読み込みを開始
const stream = new ReadableStream({
start(controller) {
// データをバイト単位で読み込み
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
push();
});
}
push();
}
});
return new Response(stream);
})
.then(response => {
// ダウンロード完了後の処理
console.log('Download complete!');
})
.catch(error => {
console.error('Error during fetch:', error);
});
このコードは、基本的にデータをダウンロードし、読み込んだバイトデータをストリームとして処理します。進行状況の追跡は、ReadableStreamの実装をカスタマイズすることで可能です。
2. 進行状況の追跡
進行状況を追跡するためには、fetch()で取得したレスポンスのbodyをReadableStreamで読み込んでいきます。ReadableStreamでは、ストリームをバイト単位で読み込むことができますが、その際に、どれだけのデータを処理したかを追跡する方法があります。
進行状況の追跡方法
以下のコードでは、ダウンロードの進行状況を追跡し、ユーザーにフィードバックを提供する方法を示します。
javascriptfetch('https://example.com/largefile')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
const totalBytes = parseInt(response.headers.get('Content-Length'), 10); // ダウンロードするファイルのサイズ
let loadedBytes = 0; // 読み込んだデータのバイト数
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
loadedBytes += value.length;
const progress = (loadedBytes / totalBytes) * 100; // 進行状況の計算
console.log(`Download progress: ${Math.round(progress)}%`);
controller.enqueue(value);
push();
});
}
push();
}
});
return new Response(stream);
})
.then(response => {
console.log('Download complete!');
})
.catch(error => {
console.error('Error during fetch:', error);
});
このコードでは、ファイルの全体サイズ(Content-Lengthヘッダー)を取得し、ダウンロード進行状況を計算しています。loadedBytesは、読み込んだデータの合計バイト数を追跡し、進行状況をパーセンテージで表示します。
3. 進行状況を表示するUIの作成
進行状況を計算できたら、次はそれをUIで表示する方法です。たとえば、プログレスバーを表示して、ユーザーにダウンロードの進行状況を視覚的に知らせることができます。
プログレスバーの作成
HTMLに以下のようなプログレスバーを追加します。
html<progress id="progressBar" value="0" max="100">progress>
そして、JavaScriptでプログレスバーを更新するコードを追加します。
javascriptfetch('https://example.com/largefile')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
const totalBytes = parseInt(response.headers.get('Content-Length'), 10);
let loadedBytes = 0;
const reader = response.body.getReader();
const progressBar = document.getElementById('progressBar');
const stream = new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
loadedBytes += value.length;
const progress = (loadedBytes / totalBytes) * 100;
progressBar.value = progress; // プログレスバーの値を更新
controller.enqueue(value);
push();
});
}
push();
}
});
return new Response(stream);
})
.then(response => {
console.log('Download complete!');
})
.catch(error => {
console.error('Error during fetch:', error);
});
このコードでは、ダウンロードの進行状況に合わせてプログレスバーの値を更新しています。progressBar.valueに進行状況を反映させることで、ユーザーがダウンロードの進行状況をリアルタイムで確認できるようになります。
4. ダウンロードの中断
ダウンロード中に進行状況を追跡しながら、中断することも可能です。AbortControllerを使用すると、fetch()リクエストを中断することができます。
中断する方法
javascriptconst controller = new AbortController();
const signal = controller.signal;
fetch('https://example.com/largefile', { signal })
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
const totalBytes = parseInt(response.headers.get('Content-Length'), 10);
let loadedBytes = 0;
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
loadedBytes += value.length;
const progress = (loadedBytes / totalBytes) * 100;
console.log(`Download progress: ${Math.round(progress)}%`);
controller.enqueue(value);
push();
}).catch(error => {
console.error('Reading error:', error);
controller.error(error);
});
}
push();
}
});
return new Response(stream);
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Download aborted');
} else {
console.error('Download failed:', error);
}
});
// 中断操作を呼び出す例
setTimeout(() => controller.abort(), 5000); // 5秒後に中断
このコードでは、AbortControllerを使用して、指定した時間後にダウンロードを中断する処理を示しています。controller.abort()を呼び出すことで、ダウンロードが途中で停止します。
まとめ
JavaScriptでデータのダウンロード進行状況を追跡する方法と、それを中断する方法について詳しく説明しました。fetch()とReadableStreamを使って進行状況を計算し、プログレスバーを更新することができ、AbortControllerを利用してダウンロードを中断することも可能です。これらの技術を組み合わせることで、ユーザーに対してより良い体験を提供することができます。
