2015-07-10 86 views
5

mongodb集合中有20,000條記錄。我在csv中導出所有這些記錄。我用這個發送部分響應:Nodejs發送部分響應

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

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

上面的代碼一批500我使用此代碼時,所有記錄都處理結束時執行。

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

但我得到這個錯誤:

不能設置頭髮送之後。

但我得到的文件下載了500條記錄。

這是我的完整代碼。

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

你能展現完整的代碼?問題不在於你放在這裏。理想狀態下運行並查看問題(嘲笑數據可能是個好主意)。 –

+0

在批量操作完成之前,您正在發回響應。 – bluesman

+0

現在問題已解決。 http://stackoverflow.com/questions/31339652/nodejs-send-partial-response/31398864#31398864 – Rohit

回答

1

本聲明

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

屬於當你的反應是send.So到標題部分,將它發送頭。
res.end()也發送頭。所以,用這種方法你再次發送頭。

請參考這個stackoverlflow問題


編輯代碼:

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

請參考這一個多pipe

+0

即使未執行此條件,我也收到了錯誤。 – Rohit

2

爲什麼不只是流中的數據?你可以使用貓鼬query.stream功能。來自文檔的示例:

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

該流將爲您處理數據流。作爲Node.js的流,還可以監聽事件:

// 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

提交答案時,請向您的代碼添加一些說明。 – MayorMonty

+0

確實。一些代碼解釋應該是有序的。 – MoshMage

+0

將寫入作爲部分響應立即發送數據,還是將數據寫入緩衝區,等待發送? – 2017-06-05 13:44:23