Загружает несколько изображений с полем файлов - PullRequest
0 голосов
/ 23 апреля 2020

В последние несколько дней я испытываю затруднения из-за того, как загружать несколько изображений на firebase с помощью busboy. Я хочу использовать 3 поля с 3 разными изображениями. так что я могу хранить его в одной папке. Я также хочу, чтобы изображение имело имя поля

Я нашел один топи c, который помог мне использовать Promise.all и forEach, но у меня не получилось

  • хранение всех файлов в массиве
    var Promise = require('promise');
    const Busboy = require("busboy");
    const fs = require("fs");
    const os = require("os");
    const path = require("path");


    const busboy = new Busboy({ headers: req.headers });
    let imageToAdd = {};
    let imagesToUpload = []
    let newFileName;

    busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
        const imageExtension =  filename.split('.')[filename.split('.').length - 1];
        filename = `${fieldname}.${imageExtension} `
        newFileName = filename
        const filepath = path.join(os.tmpdir(), filename);
        imageToAdd = { file: filepath, type: mimetype };
        file.pipe(fs.createWriteStream(filepath));
        imagesToUpload = [...imagesToUpload, imageToAdd]
    });
  • l oop над массивом файлов и сохранение обещаний в новом массиве
  • , а затем ожидание разрешения всех обещаний с Promise.all
    busboy.on("finish", () => {
        let promises = []
        imagesToUpload.forEach((imageToBeUploaded) => {
            promises.push(
                admin
                .storage()
                .bucket(`${config.storageBucket}`)
                .upload(imageToBeUploaded.file, {
                    resumable: false,
                    destination: `projectname/${newFileName}`,
                    metadata: {
                        metadata: {
                          contentType: imageToBeUploaded.type,
                        }
                    }
                })          
            )     

        }) 
        Promise.all(promises)
        .then(res => { 
            res.status(200).json({msg: 'Successfully uploaded all images')
        })
        .catch(err => {
            res.status(500).json({error: err.code})
        })
    })
    busboy.end(req.rawBody);
})

Только последнее изображение хранится в моем хранилище базы данных.

Кто-нибудь может мне помочь с этим?

спасибо

1 Ответ

0 голосов
/ 23 апреля 2020

У вас есть только один newFileName в вашем коде, а у вас есть массив imagesToUpload. Таким образом, вы загружаете каждое из этих изображений в один и тот же newFileName и в конечном итоге выбираете, какой из загрузок завершится последним.

Вы захотите сохранить массив newFileNames, чтобы он соответствовал массив imagesToUpload.

что-то вроде:

const busboy = new Busboy({ headers: req.headers });
let imageToAdd = {};
let imagesToUpload = []
let newFileNames = [];

busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
    const imageExtension =  filename.split('.')[filename.split('.').length - 1];
    filename = `${fieldname}.${imageExtension} `
    const filepath = path.join(os.tmpdir(), filename);
    imageToAdd = { file: filepath, type: mimetype };
    file.pipe(fs.createWriteStream(filepath));

    imagesToUpload.push(imageToAdd);
    newFileNames.push(filename);
});

...

busboy.on("finish", () => {
    let promises = imagesToUpload.map((imageToBeUploaded, index) => {
        admin
        .storage()
        .bucket(`${config.storageBucket}`)
        .upload(imageToBeUploaded.file, {
            resumable: false,
            destination: `projectname/${newFileNames[index]}`,
            metadata: {
                metadata: {
                  contentType: imageToBeUploaded.type,
                }
            }
        })          
    }) 
    Promise.all(promises)
      ...
...