DINGDANGMAOUP
DINGDANGMAOUP
Published on 2024-08-08 / 52 Visits
0
0

单文件并行分块上传

//单文件并行分块上传

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);
}


Comment