问题
I use busboy connect to get the upload data from my client. I try to save the data and then on.finish to return status ok to the server. The problem is that the on.finish fires before the end of the file saving. Have I done something wrong or that's the way the module works?
server-side code :
console.log("upload started dirname ", __dirname);
var fstream;
var result = [];
var number_of_files = 1;
req.pipe(req.busboy);
req.busboy.on('field', function(fieldname, val) {
field_obj = {}
field_obj[fieldname] = val;
result.push(field_obj);
console.log(field_obj)
});
req.busboy.on('file', function(fieldname, file, filename) {
console.log("Uploading: " + filename);
//Path where image will be uploaded
if (result.length > 0) {
var file_type = filename.substr(filename.length - 4);
filename = result[0].name + '_' + number_of_files + file_type;
number_of_files++;
}
fstream = fs.createWriteStream(__dirname + "/" + filename);
file.pipe(fstream);
fstream.on('close', function() {
console.log("Upload Finished of " + filename);
result.push(filename);
console.log("result ",result)
});
});
req.busboy.on('finish', function() {
console.log("form parsing finished")
console.log("result finish",result)
res.sendStatus(200)
});
I would expect the "result finish" to be the last msg i see , but i get the following on my console:
Uploading: testSwf1.swf
Uploading: testSwf3.swf
form parsing finished
result finish [ { name: '123' }, { clickUrl: '234234' } ]
Upload Finished of 123_1.swf
result [ { name: '123' }, { clickUrl: '234234' }, '123_1.swf' ]
Upload Finished of 123_2.swf
result [ { name: '123' },
{ clickUrl: '234234' },
'123_1.swf',
'123_2.swf' ]
EDIT i also tried the on.end but that one didn't fired at all.
req.busboy.on('end', function() {
console.log("DONE PARSING FORM")
console.log("NEW result finish", result)
});
回答1:
This is expected behavior. finish
is emitted when the last of the data has been read from the request (this includes any/all emitted file
streams, which are subsets of the incoming request data).
However if you're writing a file
stream to disk, it's possible for the file
stream to still have the last chunk(s) of data still buffered in memory. This is why the file may not be completely written to disk by the time finish
is emitted.
One common solution for this is to both check a flag that gets set in the busboy finish
event handler, and check a counter variable that gets incremented for every fstream close
event (comparing it to result.length
for example).
回答2:
As mscdex suggested I used a variable to find when the writing is finised:
var fstream;
var result = [];
var number_of_files = 1;
var counter = 0;
req.pipe(req.busboy);
req.busboy.on('field', function(fieldname, val) {
field_obj = {}
field_obj[fieldname] = val;
result.push(field_obj);
console.log(field_obj)
});
req.busboy.on('file', function(fieldname, file, filename) {
counter++;
console.log("Uploading: " + filename);
//Path where image will be uploaded
if (result.length > 0) {
var file_type = filename.substr(filename.length - 4);
filename = result[0].name + '_' + number_of_files + file_type;
number_of_files++;
}
fstream = fs.createWriteStream(__dirname + "/" + filename);
file.pipe(fstream);
fstream.on('close', function() {
counter--;
console.log("Upload Finished of " + filename);
result.push(filename);
console.log("result ",result)
if(counter == 0){
console.log("writing finished");
res.sendStatus(200);
}
});
});
来源:https://stackoverflow.com/questions/32009583/busboy-connect-fires-on-finish-before-the-end-of-save-file-node-js-express