2016-04-12 20 views
2

Veritabanını birden çok kez isteyerek elde ettiğim verileri içeren bir yanıt göndermek istediğim bu koda sahibim. Neden boş bir cevap gönderdiğini anlamıyorum.Yapım json yanıtı. NodeJS boş yanıt gönder

var express = require('express'), 
router = express.Router(), 
database = require('../database'); 

router.get('/', function(req, res, next){ 

    res.writeHead(200, {"Content-Type": "application/json"}); 

    var ttt; 
    var yyy; 

    database.getTagType().then(function(data) { 
     ttt = "pfff"; 
    }); 

    database.getSpecie().then(function(data) { 
     yyy = "akkhhh"; 
    }); 

    var json = JSON.stringify({ 
    anObject: ttt, 
    anArray: yyy, 
    }); 
    res.end(json); 

}); 

module.exports = router; 
+0

Vaatler eşzamanlı değildir :) dile eklenir alır. – arthurakay

cevap

4

Sorun, Promise.then'un eşzamansız yapısındadır. Gördüğünüz gibi, sözlerin her ikisi de çözülmeden önce JSON.stringify ve res.end çağrılır. Yanıtı yalnızca tüm veriler getirildiğinde göndermek için Promise.all yöntemini kullanmanız gerekir.

router.get('/', function(req, res, next){ 
    var promises = []; 

    promises.push(database.getTagType().then(function(data){ 
     return "pfff"; 
    })); 

    promises.push(database.getSpecie().then(function(data) { 
     return "akkhhh"; 
    })); 

    Promise.all(promises).then(function(values) { 
     // Actually, express can stringify response for us. Also it adds 
     // correct "Content-Type" header. 
     res.json({ 
      anObject: values[0], 
      anArray: values[1] 
     }); 
    }).catch(function(error) { 
     // Something went wrong. Let the error middleware deal with the problem. 
     next(error); 
     // Instead we can just send an error response, like so: 
     // res.status(500).json({error: error.toString()}); 
    }); 
}); 
+1

'catch' bloğunu ekleyin, çünkü mevcut kodunuzla, kullanıcı herhangi bir hata ortaya çıkarsa hiçbir zaman bir yanıt almayacaktır. – alexmac

+0

Haklısınız, bildirim için teşekkür ederim. Cevabı güncelledim. –

+0

Açıklık getirdiğiniz için teşekkürler, sorun çözüldü – Soumia

1

veritabanı aramaları asenkron şunlardır: Burada

bu yapılabilir nasıl bir örnektir. Sözler geri dönüyorlar ve then işlevlerini ekliyorsunuz, ancak javascript işlevi çalışıyor, işlev getTagType ve getSpecie işlevlerini çağırıyor ve ardından cevabını yanıtları göndermeden önce ve db çağrısı bitti.

Yanıtla yanıt vermeden önce çözülmesi gereken tüm vaatleri beklediğinizden emin olmalısınız, bu temelde then() işlevlerini iç içe geçirmeyi gerektirir. böylece gibi

: Bu fonksiyon hemen dönecektir, ancak veritabanı aramaları tamamlanana kadar res.end() aramayacağım

router.get('/', function(req, res, next){ 

    res.writeHead(200, {"Content-Type": "application/json"}); 

    var tag = database.getTagType(); 
    // `tag` is now a promise 

    var specie = database.getSpecie(); 
    // `specie` is a promise 

    Promise.all([tag, specie]).then(function(values) { 
    // this code is executed once both promises have resolved, the response has come back from the database 

     var json = JSON.stringify({ 
      tag: values[0], 
      specie: values[1] 
     )}; 

     res.end(json); 
    }); 
}); 

.

Bu kod Yanıtınız için size `json` nesne oluşturmak zaman ttt` ve` yyy` henüz atanmamış `yüzden, daha temiz bir kez async/await

+0

Çok teşekkürler, sorun çözüldü – Soumia

+0

@ user2795508, bir kişinin "kabul edildi" şeklinde yanıtını işaretleyebilir, böylece insanlar çözdüğünü biliyor mu? Cevabın yanında onay işareti olmalıdır. – TinyTimZamboni

+0

Kontrol ettim, teşekkürler;) – Soumia