Search code examples
javascriptpromisebluebird

Queueing file uploads with Promise.map


The first set of files is uploaded successfully, but as soon as it is done, it does not start the next set in the queue.

Why does the iteration stop after the first set and how do I fix this issue?

The solution does not have to use Bluebird necessarily – I used it in the first place, because I thought, I would turn out to be easier.

function uploadFile(url, file, onProgress) {

    return new Promise((resolve, reject) => {

        const formData = new FormData();
        formData.append('file', file);

        const xhr = new XMLHttpRequest();

        xhr.open('POST', url);

        xhr.addEventListener('readyState', _ => {
            if (xhr.readyState === xhr.DONE) {
                resolve(file);
            }
        });

        xhr.addEventListener('error', _ => {
            reject(new Error());
        });

        xhr.upload.addEventListener('progress', event => {
            onProgress && onProgress(event.loaded / event.total);
        });

        xhr.send(formData);

    });

}

/* files is a FileList */
Promise.map(Array.from(files), file => {
    return uploadFile(location.href, file, null);
}, { concurrency: 2 });

Solution

  • The event type is called readystatechange (not readyState).

    As powerc9000 noticed in the comments, the Promise does not get resolved and Promise.map does not know when to continue.