//单文件并行分块上传
const MIN_PART_SIZE = 5 * 1024 * 1024; // 5MB
const MAX_CONCURRENT = 3;
function uploadPart(key: string, uploadId: string, partNumber: number, file: File) {
return new Promise<void>((resolve, reject) => {
const start = partNumber * MIN_PART_SIZE;
const end = Math.min(start + MIN_PART_SIZE, file.size);
const part = file.slice(start, end);
const formData = new FormData();
formData.append('key', key);
formData.append('uploadId', uploadId);
formData.append('partNumber', partNumber.toString());
formData.append('part', part);
fetch('https://api.example.com/upload', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to upload part');
}
resolve();
})
.catch(reject);
}
);
}
async function parallelUpload(key: string, uploadId: string, file: File) {
const partCount = Math.ceil(file.size / MIN_PART_SIZE);
const uploadTasks: Promise<void>[] = [];
const concurrentTasks = new Set();
const addToQueue = async (partNumber: number) => {
while (concurrentTasks.size >= MAX_CONCURRENT) {
// @ts-ignore
await Promise.race([...concurrentTasks]);
}
const uploadTask = uploadPart(key, uploadId, partNumber, file);
concurrentTasks.add(uploadTask);
uploadTask.then(() => {
concurrentTasks.delete(uploadTask);
});
uploadTasks.push(uploadTask);
}
for (let i = 0; i < partCount; i++) {
await addToQueue(i);
}
await Promise.all(uploadTasks);
}