2015-07-10 16 views
5

Es gibt 20.000 Datensätze in Mongodb-Sammlung. Ich exportiere alle diese Datensätze in einem CSV. Ich bin senden Teilantwort dies mit:Nodejs senden teilweise Antwort

res.writeHead(200, { 
        "Content-Type": "application/csv", 
        "Content-disposition": "attachment; filename='import.csv'" 
}); 

res.write(data + '0', "binary"); 

Above-Code wird in Batch von 500 Ausführen ich mit diesem Code bin endet, wenn alle Datensätze verarbeitet werden.

if (++responseCount == loopCount) { 
    res.end(); 
} 

Aber ich habe diesen Fehler:

kann nicht Header gesetzt, nachdem sie gesendet werden.

Aber ich bekomme die Datei mit 500 Datensätzen heruntergeladen.

Hier ist mein voller Code.

var exportData = function (req, res, next) { 

var limit = 500; 
var responseCount = 0; 
var loopCount = 1; 
var size = 30000; 

//Get 500 records at one time 
var getData = function (req, start, cb) { 
    req.db.collection('items').find().skip(start).limit(limit).toArray(function (err, records) { 
     if (err) throw err; 
     cb(null, records); 
    }); 
}; 

if (size > limit) { 
    loopCount = parseInt(req.size/limit); 

    if ((req.size % limit) != 0) { 
     loopCount += 1; 
    } 
} 

for (var j = 0; j < loopCount; j++) { 

    getData(req, limit * j, function (err, records) { 

     if (err) throw err; 

     records.forEach(function (record) { 
      //Process record one by one 
     }); 

     res.write(records); 

     if (++responseCount == loopCount) { 
      res.setHeader('Content-type', 'application/csv'); 
      res.setHeader("Content-disposition", 'attachment; filename="import.csv"'); 
      res.end(); 

     } 

    }); 
} 
}; 
+0

Können Sie Ihren vollständigen Code zeigen? Das Problem liegt nicht in dem, was du hier angegeben hast. Idealerweise, um das Problem zu lösen und zu sehen (eine Verspottung der Daten könnte eine gute Idee sein). –

+0

Sie senden die Antwort zurück, bevor die Stapelverarbeitung abgeschlossen ist. – bluesman

+0

Problem ist jetzt gelöst. http://stackoverflow.com/questions/31339652/nodejs-send-partial-response/31398864#31398864 – Rohit

Antwort

1

Diese Aussage

res.writeHead(200, { 
        "Content-Type": "application/csv", 
        "Content-disposition": "attachment; filename='import.csv'" 
}); 

gehört Abschnitt Header, wenn Sie Antwort ist send.So, es Header senden.
res.end() senden Sie auch header.So, auf diese Weise senden Sie Header erneut.

Bitte beachten Sie diese einer stackoverlflow Frage


EDIT CODE:

data.pipe(resp); 
resp.end(); 

Bitte beachten Sie diese für mehr pipe

+0

Ich habe Fehler erhalten, auch wenn diese Bedingung nicht ausgeführt wird. – Rohit

2

Warum nicht einfach die Daten streamen? Sie könnten Mungo query.stream Feature verwenden. Ein Beispiel aus der Dokumentation:

// follows the nodejs 0.8 stream api 
Thing.find({ name: /^hello/ }).stream().pipe(res) 

Der Stream kümmert sich um den Datenfluss für Sie. Als node.js Strom, können Sie auch für Veranstaltungen hören:

// manual streaming 
var stream = Thing.find({ name: /^hello/ }).stream(); 

stream.on('data', function (doc) { 
    // do something with the mongoose document 
}).on('error', function (err) { 
    // handle the error 
}).on('close', function() { 
    // the stream is closed 
}); 
1
var exportData = function (req, res, next) { 

    res.writeHead(200, { 
     'Content-Type': 'application/csv', 
     'Content-Disposition': 'attachment; filename="import.csv"' 
    }); 

    var limit = 500; 
    var responseCount = 0; 
    var loopCount = 1; 
    var size = 30000; 

    //Get 500 records at one time 
    var getData = function (req, start, cb) { 
     req.db.collection('items').find().skip(start).limit(limit).toArray(function (err, records) { 
      if (err) throw err; 
      cb(null, records); 
     }); 
    }; 

    if (size > limit) { 
     loopCount = parseInt(req.size/limit); 

     if ((req.size % limit) != 0) { 
      loopCount += 1; 
     } 
    } 

    for (var j = 0; j < loopCount; j++) { 

     getData(req, limit * j, function (err, records) { 

      if (err) throw err; 

      records.forEach(function (record) { 
       //Process record one by one 
      }); 

      res.write(records); 

      if (++responseCount == loopCount) { 
       res.end(); 
      } 

     }); 
    } 
}; 
+1

Wenn Sie Antworten senden, fügen Sie Ihrem Code bitte eine Erläuterung hinzu. – MayorMonty

+0

In der Tat. Einige Code-Erklärung sollte in Ordnung sein. – MoshMage

+0

Wird Schreiben die Daten sofort senden, als Teilantwort, oder schreiben Sie die Daten in einen Puffer, warten auf den Versand? –

Verwandte Themen