Используя nodejs и express, я хотел бы вернуть один или несколько объектов (массив) с помощью JSON. В приведенном ниже коде я выводю по одному объекту JSON за раз. Это работает, но это не совсем то, что я хочу. Полученный ответ не является действительным ответом JSON, поскольку у меня много объектов.
Я прекрасно понимаю, что могу просто добавить все объекты в массив и вернуть этот конкретный массив в res.end. Однако я боюсь, что это может стать тяжелым для обработки и потребовать много памяти.
Как правильно добиться этого с помощью nodejs? Является ли query.each правильным методом вызова?
app.get('/users/:email/messages/unread', function(req, res, next) {
var query = MessageInfo
.find({ $and: [ { 'email': req.params.email }, { 'hasBeenRead': false } ] });
res.writeHead(200, { 'Content-Type': 'application/json' });
query.each(function(err, msg) {
if (msg) {
res.write(JSON.stringify({ msgId: msg.fileName }));
} else {
res.end();
}
});
});
res.write(JSON.stringify(foo))
. Если онfoo
большой, вам может потребоваться его нарезать (преобразовать в строку, а затем записать фрагмент за раз). Возможно, вы также захотите разместить свой заголовок"Content-Type":"application/json"
или что-то подобное.Я не знаю, действительно ли это другое, но вместо того, чтобы перебирать курсор запроса, вы могли бы сделать что-то вроде этого:
query.exec(function (err, results){ if (err) res.writeHead(500, err.message) else if (!results.length) res.writeHead(404); else { res.writeHead(200, { 'Content-Type': 'application/json' }); res.write(JSON.stringify(results.map(function (msg){ return {msgId: msg.fileName}; }))); } res.end(); });
источник
[Edit] После просмотра документации Mongoose выяснилось, что вы можете отправлять каждый результат запроса как отдельный блок; веб-сервер по умолчанию использует фрагментированную кодировку передачи , поэтому все, что вам нужно сделать, это обернуть элементы массивом, чтобы сделать его допустимым объектом JSON.
Примерно (не проверено):
app.get('/users/:email/messages/unread', function(req, res, next) { var firstItem=true, query=MessageInfo.find(/*...*/); res.writeHead(200, {'Content-Type': 'application/json'}); query.each(function(docs) { // Start the JSON array or separate the next element. res.write(firstItem ? (firstItem=false,'[') : ','); res.write(JSON.stringify({ msgId: msg.fileName })); }); res.end(']'); // End the JSON array and response. });
В качестве альтернативы, как вы упомянули, вы можете просто отправить содержимое массива как есть. В этом случае тело ответа будет помещено в буфер и немедленно отправлено, что может потребовать большого количества дополнительной памяти (сверх того, что требуется для хранения самих результатов) для больших наборов результатов. Например:
// ... var query = MessageInfo.find(/*...*/); res.writeHead(200, {'Content-Type': 'application/json'}); res.end(JSON.stringify(query.map(function(x){ return x.fileName })));
источник