2012-01-18 13 views
79

Düğüm ve ifade kullanarak, JSON kullanarak bir veya daha çok nesneyi (dizi) döndürmek istiyorum. Aşağıdaki kodda bir seferde bir JSON nesnesini çıkardım. İşe yarıyor ama bu tam olarak istediğim şey değil. Üretilen yanıt, birçok nesneye sahip olduğumdan geçerli bir JSON yanıtı değil.Node.js ile karmaşık bir JSON yanıtı nasıl verilir?

Tüm nesneleri bir diziye ekleyebileceğimi ve belirli diziyi res.end'e döndürebileceğimin farkındayım. Ancak korkarım ki bu işlem yoğunlaşabilir ve hafızada yoğun olabilir.

Bunu nodejs ile elde etmenin doğru yolu nedir? Query.aracı aramak için doğru yöntem mi?

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(); 
     } 
    }); 
}); 

cevap

181

ekspres 3 sitemizden yapabilirsiniz res.json doğrudan kullanmak ({foo: barda})

res.json({ msgId: msg.fileName }) 

Bu iyi bir fikir documentation

+7

Bunu ifade etmeksizin nasıl yapmalı? – Piotrek

+0

@ Ludwik11 'res.write (JSON.stringify (foo))'. Eğer 'foo' büyükse, onu doğramak zorunda kalabilirsiniz (stringify, sonra bir kerede chunk yazın). Muhtemelen ayrıca "İçerik-Türü" başlığınızı da görmek istersiniz: "uygulama/json" veya uygun şekilde benzer. – OJFord

12

ayrı yığın olarak her sorgu sonucunu gönderebilir gibi görünüyor Gelincik belgeleri inceledikten sonra [Düzenle]; Web sunucusu, chunked transfer encodingby default kullanır, böylece yapmanız gereken tek şey, geçerli bir JSON nesnesi yapmak için öğelerin etrafında bir dizi sarmaktır.

Kabaca (denenmemiş): Eğer söz olarak olduğu gibi

Alternatif
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. 
}); 

, sadece dizi içeriğini gönderebilir. Bu durumda the response body will be buffered ve hemen gönderilir, büyük sonuç kümeleri için büyük miktarda ek bellek (sonuçları saklamak için gerekenleri) tüketebilir. Örneğin:

// ... 
var query = MessageInfo.find(/*...*/); 
res.writeHead(200, {'Content-Type': 'application/json'}); 
res.end(JSON.stringify(query.map(function(x){ return x.fileName }))); 
+0

bakınız. Ancak bana biraz rahatsız görünüyor. Nodejs'in biraz daha zarif bir şey vermesini umuyordum. – Martin

18

bu gerçekten herhangi farklı ise bilmiyorum, daha çok sorgu imlecin üzerinde yineleme yerine, böyle bir şey yapabileceğini:

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(); 
});