2013-08-02 3 views
3

node.js가 비동기 적으로 실행된다는 것을 알고 있기 때문에 외부 함수가 내부보다 먼저 실행됩니다. 그러나 for 루프 밖에서 알림 배열에 액세스하는 방법은 무엇입니까? 한 번에 배열의 모든 값에 액세스하고 싶습니다. 이것이 가능합니까?노드 js의 함수 외부에있는 배열에 액세스

var notification=[]; 

for(var j=0;j<6; j++) 
{ 
    getNotification(response[j].sender_id,function(results)  // a function called 
    { 
     notification[j] =results; 
     console.log(notification); // output: correct 
    });   
} 
console.log(notification);  // output: [], need notification array values here 
+0

발생한 오류가 무엇입니까? –

+0

수 없습니다. 적어도 안정적으로, 당신이 가지고있는 것은 경쟁 조건이며, 그것은 잃어 버리게 될 것입니다. 콜백에서 사용합니다. 그러나 콜백이 완료되면 알림을 클로저에 보관하고 다른 기능에서 사용하여 사용자가이를 수행하는 것처럼 보이게 할 수 있습니다. 이것은 정확히 콜백의 목적입니다. 일부 비동기 작업 범위 내에서 일련의 작업을 실행합니다. – ChrisCM

+0

또한 루프에서 함수를 만드는 것은 나쁜 생각입니다. for 루프 밖에서 콜백을 정의하고 인수로 사용해야합니다. – ChrisCM

답변

1

EDIT : 제 3 자 라이브러리를 사용하지 않으려는 경우 이는 사용자 코드에서 수행하는 방법입니다.

/* jshint node:true*/ 


function getNotifications(responses, callbackToMainProgramLogic) { 
    'use strict'; 
    var results = []; 

    function getNotificationAsync(response) { 
     getNotification(response.sender_id, function (data) { 
      results.push(data); 

      if (responses.length) { 
       getNotificationAsync(responses.pop());//If there are still responses, launch another async getNotification. 
      } else { 
       callbackToMainProgramLogic(results);//IF there aren't we're done, and we return to main program flow 
      } 
     }); 
    } 

    getNotificationAsync(responses.pop()); 
} 

getNotifications(someArrayOfResonses, function (dataFromNotifications) { 
    console.log('The collected data: ' + JSON.stringify(dataFromNotifications, 0, 4)); 
}); 

절대적으로 필요한 경우 이와 같이 어리석은 행동을 할 수 있습니다. loopUntilDatReceived의 논리는 비어 있지 않은 문자열을 기다리지 않고 배열 크기를 기다리고있을 것입니다. 그러나 아이디어는 비슷하며 어쨌든 이것을 사용해서는 안됩니다! :)

var fileData = ''; 
fs.readFile('blah.js', function (err, data) { //Async operation, similar to your issue. 
    'use strict'; 
    fileData = data; 
    console.log('The Data: ' + data); 
}); 

function loopUntilDataReceived() { 
    'use strict'; 
    process.nextTick(function() {//A straight while loop would block the event loop, so we do this once per loop around the event loop. 
     if (fileData === '') { 
      console.log('No Data Yet'); 
      loopUntilDataReceived(); 
     } else { 
      console.log('Finally: ' + fileData); 
     } 
    }); 
} 

loopUntilDataReceived(); 

나는 이것이 우스꽝 스럽다는 것을 언급 했습니까? 솔직히 말해서, 이것은 끔찍한 생각이지만 Node 이벤트 루프가 어떻게 진행되는지, 그리고 노드 이벤트 루프가 어떻게 작동하는지 이해하는 데 도움이 될 수 있습니다. 그리고 왜 콜백과 흐름 제어 라이브러리에 대한 다른 글들도 갈 길이 멀다.

0

은 다음과 같이 통지 루프에 콜백을 보내기 :

var notification=[]; 

getNotificationArray(function() { 
    console.log(notification); 
}); 

function getNotificationArray (callback) 
{ 
    for(var j=0;j<6; j++) 
    { 
    getNotification(response[j].sender_id,function(results)  // a function called 
    { 
     notification[j] =results; 
     console.log(notification); // output: correct 
    });   
    } 
    callback(); 
} 
+0

사실, 죄송합니다. 작동하지 않습니다. 콜백이 잘못된 장소에 있다는 것을 깨달았습니다. getNotification()은 비동기 부분입니다. 따라서 콜백()이 제대로 배치되지 않았으므로 반복이 진행되므로 getNotification을 여러 번 반복 할 때까지 기다리는 로직이 필요합니다. – ChrisCM

+0

네, 이제 나에게 일어난다. – frhd

+0

시도한 것과 비슷한 제 3 자 이외의 lib 함수를 포함하도록 답변을 업데이트했습니다. 확인 해봐. – ChrisCM

0

첫째, 당신이

다음 (자세한 here 참조) 코드에서 폐쇄 문제가있어, 이 시점에서 값이 준비되지 않았기 때문에 단순히 루프 옆에 배열 값을 가질 수 없습니다. 6 개의 getNotification 호출이 모두 해결 될 때까지 기다려야합니다. async 라이브러리로이 작업을 수행 할 수 있습니다. 예 :

var notification = []; 

function createRequest (index) { 
    return function (callback) { 
     getNotification(response[index].sender_id, function(results) { 
      notification[index] = results; 
      callback(results); 
     }); 
    } 
} 

var requests = []; 
for(var j=0;j<6; j++) { 
    requests.push(createRequest(j)); 
} 

async.parallel(requests, function (allResults) { 
    // notifications array is ready at this point 
    // the data should also be available in the allResults array 
    console.log(notifications); 
});