2 votes

Comment utiliser l'événement stop côté serveur lorsque tous les fichiers sont téléchargés dans jQuery File Upload ?

J'utilise jQuery File Upload sur express.js avec jquery-file-upload-middleware et mongoose avec mongoDB.

Je veux télécharger les images d'une galerie. L'objet Galery contient un tableau d'objets Image, tels que

var GalerySchema = new mongoose.Schema({
    images: [ImageSchema]
})

Après que chaque fichier ait été téléchargé de manière asynchrone, je veux le pousser dans le tableau des images de mon objet Galery.

J'ai essayé de faire ce qui suit côté serveur :

// Is called everytime an image is uploaded
upload.on('end', function(fileInfo, rew, res){
    // Get the galery
    db.Galery.findOne({_id: req.fields.galery_id}, function(err, galery){

        // Create new Image object instance
        var image = new db.Image({src: fileInfo.name});

        // Save, in order to create auto generated _id
        image.save(function(err){
            if(err) {console.log(err); return; }

            // Add to Images array of Galery object
            galery.images.push(image);

            // Save galery with added image
            galery.save(function(err){
                if(err) { console.log(err); return; }
            });
        })
    });
});

En faisant cela, j'obtiens un bien connu [VersionError: No matching document found.] L'accès simultané au même document mongodb est, à ma connaissance, dû au fait que le téléchargement est asynchrone.

Donc, pour traiter le problème de manière asynchrone, il serait bon d'attendre que tous les téléchargements soient terminés, puis d'insérer les images une par une dans la base de données mongole, c'est-à-dire en utilisant la méthode suivante async.parallel() .

Mais comment puis-je accéder à l'événement de tous les téléchargements ayant été terminés ?

Je sais que du côté du navigateur, je peux utiliser le événement d'arrêt . Mais d'abord, cela ne contient aucune donnée sur les fichiers téléchargés. De plus, je veux le faire du côté du serveur.

Y a-t-il quelque chose comme

upload.on('doneAll', function(allFilesInfo, req, res){...})?

0voto

Andrei Dolhescu Points 44

Vous pourriez utiliser des promesses (Bluebird : https://github.com/petkaantonov/bluebird , npm install bluebird --save ) et avoir quelque chose comme ça :

var BPromise = require('bluebird');

var uploadDone = new BPromise(function (resolve, reject) {

    // your image upload

});

uploadDone.then(function (result) {

   // upload complete here

}, function (error) {
   console.log("Error: ", error);
});

0voto

Will Points 1805

Étant donné que jQuery File Upload crée un XHR pour chaque fichier, ceux-ci sont considérés comme des POST distincts côté serveur et il n'existe aucun moyen direct pour le middleware de téléchargement de savoir quand tous les téléchargements sont terminés. Vous pourriez éventuellement créer un autre point de terminaison à utiliser comme callback pour l'événement stop, mais non seulement cela ne fournit pas d'informations sur ce qui a été téléchargé, comme vous le savez déjà, mais cela ne sera pas très utile si deux utilisateurs ou plus téléchargent en même temps.

Ce dont vous avez besoin, je crois, c'est d'employer un findOneAndUpdate (ou un findByIdAndUpdate ) pour effectuer la mise à jour sur Galery . Voir cette respuesta pour un exemple de la façon dont $push el image a galery .

0voto

Dimitri L. Points 2348

Avec le téléchargement, vous faites une demande au serveur par fichier ou une demande au total si vous utilisez la fonction sequentialUploads: true . Si vous voulez savoir quand toutes les images ont été téléchargées dans un scénario asynchrone, vous devez définir une route supplémentaire avec express et ajouter un callback au fileuploader lorsque tous les fichiers sont terminés qui appelle cette route. Ensuite, vous auriez également besoin de suivre quels fichiers ont été téléchargés et non enregistrés avant. Si votre script est utilisé par plus d'une personne (accès public ?) alors vous devrez également implémenter une certaine gestion de session pour sauvegarder les fichiers téléchargés à ajouter lorsque votre route "uploadDone" est appelée. Comme vous pouvez le constater, cela représente beaucoup de frais généraux, c'est pourquoi je vous conseille d'utiliser la fonction sequentialUploads: true solution.

Cependant, je ne crois pas que vous obteniez le [VersionError: No matching document found.] à cause de l'accès simultané au document de la galerie, puisque l'obtention / la sauvegarde du document est une question de quelques millisecondes. Je vous conseille de vérifier si le req.fields.galery_id est envoyé.

console.log(req.fields.galery_id);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X