2016-06-09 5 views
0

다음 코드는 일부 원격 서버 (kafka 브로커)에 요청 메시지를 생성하고 이에 대한 응답을 기다리기 위해 http 요청을 처리해야합니다. 응답 메시지가 도착하면 http 응답 (json 또는 something)으로 리턴되어야합니다.Node.js 비동기 함수

router.get('/status', function(req, res, next) { 
    // init the producer 
    ... 

    // 1st async function 
    producer.on('ready', function() { 
     // some code for generating payloads (data for a message) 
     ... 

     // 2nd async function 
     producer.send(payloads, function (err, data) { 
      // some log of success sending message 
      ... 

      // 3rd async function 
      consumer.on('message', function (message) { 
       // got some response message 
       res.send("message: " + message); 
      }); 
     }); 
    }); 
}); 

내 동기화가 아닌데도 동기화 할 수 있습니까?

편집 : 더 명확하게하려고합니다. 다음 코드를 고려하십시오.

function boo() { 
    // part 1 - init some consumer 
    console.log("1. finish init"); 

    // part 2 - This is async function. whenever messages will arrive - this function will be fetched. 
    consumer.on('message', function (message) { 
     console.log("2. message arrive!"); 
     return message; 
    } 

    // part 3 
    console.log("3. end function"); 
    return null; 
} 

부분 2는 1 초 후에 발생한다고 가정합니다. 결과는 다음과 같습니다.

1. finish init 
3. end function 
2. message arrive! 

목표는 비동기 메시지 (2 부)를 기다리고 값을 반환하는 것입니다. 어떻게하면 될까요?

+0

나는 문제가 발생하지 않았습니다. 질문이 뭐야? (아주 좋은 콜백 지옥, 그런데 :) –

+0

이것은 코드의 완전한 예제는 아니며 예/아니오 질문과 같이 읽습니다. 나는 또한 당신이 "함께 동기화"를 의미하는지 모르겠습니다. – Paul

+0

기본적으로 온라인에서 많은 답변을 찾을 수있는 인기있는 "비동기 코드 실행 순서"질문을합니다. – Cristy

답변

0

를 사용할 수 있습니다, 나는 node.js.하는 새 완료 Philip Roberts video을 본 후에 JavaScript가 실제로 어떻게 작동하는지 깨달았습니다. 그런 다음 전 세계 messageArray & messageId 카운터로 문제를 해결했습니다. 각 사용자 요청은 messageArray (나중에 응답하기 위해 관련 핸들러 오브젝트 포함)에 저장됩니다. 그런 다음 kafka를 통해 메시지가 내부 시스템 구성 요소로 전송됩니다. 메시지가 시스템에서 다시 도착할 때까지 사용자는 응답하지 않습니다. 메시지가 kafka 소비자 (시스템 구성 요소에서)에게 도착하면 관련 ID를 추출하고 관련 사용자에게 응답합니다. 다음은 코드입니다.

var messageId = 0; 
var messageArray= []; 

router.get('/status', function(req, res, next) { 
    var o = {id: messageId, req: req, res: res, next: next}; 
    messageArray.push(o); 
    messageId++; 

    // send message with kafka producer into the system internal components - THE MESSAGE CONTAINS THE messageId! 
}); 

consumer.on('message', function (message) { 
    // Extract the original messageId from the arrived message and look for it in the messageArray 
    var messageId = extractMessageId(message); 

    var data = dequeueMessageById(messageId); 

    // got some response message 
    data.res.send("message: " + message); 
}); 

function dequeueMessageById(messageId) { 
    for (var i=0 ; i < messageArray.length ; i++) { 
     if (messageArray[i].id == messageId) { 
      var messageData = messageArray[i]; 
      messageArray.splice(index, 1); // remove from array 
      return messageData; 
     } 
    } /* for */ 

    return null; 
} 
1

async 라이브러리를 사용할 수 있습니다.

async.series([ 
fn1, 
fn2 
], function (err, results) {  
console.log(results); 
}); 

또는이 질문을 할 때 당신이 https://github.com/AndyShin/sequenty

var sequenty = require('sequenty'); 

function f1(cb) // cb: callback by sequenty 
{ 
    console.log("I'm f1"); 
    cb(); // please call this after finshed 
} 

function f2(cb) 
{ 
    console.log("I'm f2"); 
    cb(); 
} 

sequenty.run([f1, f2]); 
+0

시리즈 대신 async.waterfall을 사용하면 안됩니까? – ItayB

+0

@ItayB : 결과를 원하는 방식에 따라 다르지만 async.waterfall은 각 함수가 결과를 다음 함수로 전달하는 반면 async.series는 최종 콜백이됩니다. – Thalaivar

+0

제 생각에 그게 스위트라고 생각하지 않아요. 두 번째 비동기 기능은 내 것이 아닙니다 (제 3 자 - 카프카 노드) - 나는 그것을 부르는 사람이 아닙니다 .. – ItayB