2017-02-11 1 views
0

여기에 제 코드가 있습니다. 내가 요청을 보낼 때, 나는 결과를 돌려주지 않을 것이다. 나는 그것이 왜 1에서 작동하지 않는지 이해하지 못했습니다. 약간 수정하고 그 안에 넣으십시오 다음, 작동하고 있습니다.노드 JS 결과를 반환하지 않습니다.

내가 여기서 잘못하고있는 것은 무엇입니까? 이유 1에서 작동하지 않는 이유는 무엇입니까?

var vigeonCollector = function(req, res) { 

// console.log(req.body); 
try { 
    var store = JSON.parse(JSON.stringify(req.body).toString('utf8').replace("'",'"')); 
} 
catch (e) { 
    console.log("Error in JSON Parsing!"); 
    return res.status(422).json({"status":false, "message":"Unparsble JSON"}); 
} 

var payloads = []; 

store.timestamp = getTimeStamp(); // Should be tagged with current timestamp. 

// Adding event_day IST and UTC format. 
var currentUTCTime = new Date(); 
var currentISTTime = new Date(currentUTCTime.toLocaleString('en-US', { timeZone: 'Asia/Kolkata' })); 
store.event_day = currentUTCTime.toLocaleString().split(',')[0]; 
store.event_day_ist = currentISTTime.toLocaleString().split(',')[0]; 
store.advertiser_id_met = store.advertiser_id; 
store.device_id_met = store.device_id; 


// Call get on redis only once and use it for attribution. 
var redis_result; 
redis.get(store.device_id).then(function(jresult){ 
    redis_result = JSON.parse(jresult); 
    console.log(redis_result); 
    if (store.event_type == "UNINSTALLS") { 

     // Attributing user installed UTM Params. 
     store.event_properties.utm_medium = redis_result.user_installed_medium; 
     store.event_properties.utm_source = redis_result.user_installed_source; 
     store.event_properties.utm_campaign = redis_result.user_installed_campaign; 
     store.advertiser_id = redis_result.advertiser_id; 

    } 
    else { 

     // Tagging last user session UTM Params. 
     store.event_properties.utm_medium = redis_result.medium; 
     store.event_properties.utm_source = redis_result.source; 
     store.event_properties.utm_campaign = redis_result.campaign; 

    } 

    temp_obj = { topic: "vnk-clst", messages: JSON.stringify(store)}; 
    payloads.push(temp_obj); 
    console.log(payloads); 
    console.log("I'm Done!"); 

}); 

producer.send(payloads, function(err, data){ 
    console.log(data); 
    if (err) return res.status(503).json({ "status": false, "message": "503 Service Unavailable", "error": err }); 
    else return res.status(200).json({ "status": true, "message": "OK"}); 
}); 

}

사례 2 :

경우 3. 같은 사례 1 res.end()를 사용하여 밖으로 경우 1에서 작동하도록하는 방법

var vigeonCollector = function(req, res) { // console.log(req.body); try { var store = JSON.parse(JSON.stringify(req.body).toString('utf8').replace("'",'"')); } catch (e) { console.log("Error in JSON Parsing!"); return res.status(422).json({"status":false, "message":"Unparsble JSON"}); } var payloads = []; store.timestamp = getTimeStamp(); // Should be tagged with current timestamp. // Adding event_day IST and UTC format. var currentUTCTime = new Date(); var currentISTTime = new Date(currentUTCTime.toLocaleString('en-US', { timeZone: 'Asia/Kolkata' })); store.event_day = currentUTCTime.toLocaleString().split(',')[0]; store.event_day_ist = currentISTTime.toLocaleString().split(',')[0]; store.advertiser_id_met = store.advertiser_id; store.device_id_met = store.device_id; // Call get on redis only once and use it for attribution. var redis_result; redis.get(store.device_id).then(function(jresult){ redis_result = JSON.parse(jresult); console.log(redis_result); if (store.event_type == "UNINSTALLS") { // Attributing user installed UTM Params. store.event_properties.utm_medium = redis_result.user_installed_medium; store.event_properties.utm_source = redis_result.user_installed_source; store.event_properties.utm_campaign = redis_result.user_installed_campaign; store.advertiser_id = redis_result.advertiser_id; } else { // Tagging last user session UTM Params. store.event_properties.utm_medium = redis_result.medium; store.event_properties.utm_source = redis_result.source; store.event_properties.utm_campaign = redis_result.campaign; } temp_obj = { topic: "vnk-clst", messages: JSON.stringify(store)}; payloads.push(temp_obj); console.log(payloads); console.log("I'm Done!"); producer.send(payloads, function(err, data){ console.log(data); if (err) return res.status(503).json({ "status": false, "message": "503 Service Unavailable", "error": err }); else return res.status(200).json({ "status": true, "message": "OK"}); }); }); } 

사례 3 : res.end() 추가 b efore 마지막}.

답변

1

사례 1의 then에 대한 호출은 사용자가 부여한 함수 내의 모든 코드가 완료 될 때까지 직접 대기하지 않습니다. 따라서 페이로드를 채우기 전에 producer.send(...)에 대한 호출이 너무 일찍 시작됩니다. 올바른 방법은 then()에 부여한 함수에 producer.send(...)을 포함시키는 것입니다. res.end()에 대한 전화는 여기에 관련이 없어야합니다.

+0

설명해 주셔서 감사합니다. 그러나 producer.send를 호출하는 https://github.com/Gowtham95india/CapVengine/blob/master/server.js statsCollector 함수를 보면 잘 작동합니다. 그것은 forEach 루프가 호출을 지연시키고 Object가 푸시 되었기 때문입니까? 그리고 당신은 producer.send가 너무 일찍 시작한다고 말합니다. 그렇다면 200을 반환해야합니다. 그렇지 않습니까? producer.send 함수에서 200을 반환하고 빈 페이로드를 보내더라도 kafka가 true를 반환해도 상관 없습니다. 설명해 주시겠습니까? –

+0

'statsCollector()'의 구현은 매우 약해서'payloads' 구조체가'producer.send()'에 전달되기 전에 완전하게 채워질 것이라는 보장이 없습니다. – Marc

+0

Promises in Javascript의 개념을 이해하고 있습니까? 그들은'then()'함수 뒤에 "live"합니다 ..... – Marc

관련 문제