概述下载队列与续传可提升大文件下载的稳定性。本文给出队列管控与续传落盘示例。队列管控与续传const dq = [];
function addDownload(url, path) { dq.push({ url, path }); }
async function processQueue() {
while (dq.length) {
const { url, path } = dq.shift();
await downloadResumeToOPFS(url, path);
}
}
async function downloadResumeToOPFS(url, path, size = 1024*1024) {
const prog = await loadProgress(path);
let offset = prog || 0;
const root = await navigator.storage.getDirectory();
const seg = path.split('/');
let dir = root; for (let i=0;i<seg.length-1;i++) dir = await dir.getDirectoryHandle(seg[i], { create: true });
const fh = await dir.getFileHandle(seg[seg.length-1], { create: true });
const ws = await fh.createWritable({ keepExistingData: true });
while (true) {
const res = await fetch(url, { headers: { Range: `bytes=${offset}-${offset+size-1}` } });
if (res.status === 416) break;
if (!res.ok && res.status !== 206) throw new Error('range failed');
const ab = await res.arrayBuffer();
const bytes = new Uint8Array(ab);
await ws.write({ type: 'write', position: offset, data: bytes });
offset += bytes.length; await saveProgress(path, offset);
if (bytes.length < size) break;
}
await ws.close();
}
function openDB(name) { return new Promise((resolve, reject) => { const r = indexedDB.open(name, 1); r.onupgradeneeded = () => { const db = r.result; if (!db.objectStoreNames.contains('prog')) db.createObjectStore('prog'); }; r.onsuccess = () => resolve(r.result); r.onerror = () => reject(r.error); }); }
async function saveProgress(key, val) { const db = await openDB('dl'); const tx = db.transaction('prog','readwrite'); tx.objectStore('prog').put(val, key); await new Promise((res, rej) => { tx.oncomplete = res; tx.onerror = () => rej(tx.error); }); db.close(); }
async function loadProgress(key) { const db = await openDB('dl'); const tx = db.transaction('prog','readonly'); const req = tx.objectStore('prog').get(key); const v = await new Promise((res, rej) => { req.onsuccess = () => res(req.result||0); req.onerror = () => rej(req.error); }); db.close(); return v; }

发表评论 取消回复