2014-12-18 6 views
0

나는 (아마도 사소한) 질문을 가지고있다. Node.js 패키지 async, 특히 async.each (https://github.com/caolan/async#forEach) 패키지를 사용하고 있습니다.Node.js async forEach : thread-safe?

var arrayOne=[]; 

async.forEach(arrayTwo, 
    function (item, callback){ 
    arrayOne.push(item); // push into arrayOne 
    callback(); // the iterator has completed 
    }, function(err) { 
    // do something with arrayOne 
}); 

이 arrayOne.push (항목) 안전한가요 :

다음 코드를 고려?

+4

node.js의 모든 내용이 스레드로부터 안전하다고 생각했습니다. 단일 스레드이며 이벤트 중심의 패러다임 이었습니까? – Siler

+0

그건 내가 아는거야. 이것이 제가 질문이 사소한 것이라고 말한 이유입니다. 그러나 비동기로 실행되는 항목은 여전히 ​​나를 조금 혼란스럽게 만듭니다. – ZzKr

+0

비동기 작업은 이벤트가 구동되므로 미래에 이벤트가 발생할 때 언젠가 발생합니다. 이벤트가 발생할 때 주 스레드가 사용되면 이벤트 처리기는 이벤트가 해제 될 때까지 대기합니다. –

답변

2

그래서 대답은 약간 미묘합니다. 이 정확한 경우에 arrayOne과 같은 항목이 arrayTwo과 같은 순서로 끝나지 만 실제로는 샘플 코드가 실제로 비동기가 아니며 지나치게 예상치 못한 일을하지 않는 부작용이 더 많습니다. 그러나이를 진정으로 신뢰할 수있게하려면 .forEach/.each 계약서에 나와 있지 않은 주문을 보장하는 async 함수를 사용해야합니다. .each은 각 항목이 arrayTwo 인 작업자 함수가 한 번 호출 될 것을 보장합니다. 순서대로 시작하거나 다음 작업을 시작하기 전에 완료 될 때까지 기다리는 것을 보장하지는 않습니다. 비동기 작성자가 성능 최적화를 위해 역순으로 작업자 함수를 시작하기로 결정한 경우 당신의 부작용. 따라서 비동기 함수의 정의/문서에서 명시 적으로 보장되는 것을 넘어선 어떠한 행동에도 의존하지 않는 것이 가장 좋습니다. 따라서 async.series과 같은 것을 사용하면 신뢰할 수있는 방법을 얻을 수 있으며 결국 arrayOne에서 예기치 않은 주문을받지 못할 수 있습니다. 물론, 병렬 처리 특성은 이제 크게 다릅니다.

그러나 기술 노트에서는 노드가 단일 실행 스레드 만 가지고 있으므로 "스레드 안전성"개념이 적용되지 않습니다. 그러나 이와 같이 비동기 코드를 처리 할 때 동일한 유형의 경쟁 조건이 생겨 결국 멀티 스레드 언어와 마찬가지로 노드의 경쟁 조건을 코딩 할 수 있습니다.

비동기 코드는 배달을 통해 음식을 주문한다는 점에서 가장 유익한 비유입니다. 3 개의 레스토랑에 전화하고 각각에서 하나의 피자를 주문하면 배달이 귀하의 문 앞에 도착하는 순서를 암시하지 않습니다.

+0

답변 해 주셔서 감사합니다. 여기서 주목해야 할 것은 두 개의 함수가'arrayOne'에서 같은 위치를 편집하는 경우 (예 : 둘 다 arrayOne [0]'을 푸시하려고하는 경우)보다는 순서입니다. 그러나 이해할 수있는 한, 이것은 node.js가 진정으로 단 하나의 스레드를 가지고 있기 때문에 문제가되지 않습니다. – ZzKr

+0

예,'arrayOne.push'를 호출해도 아무런 문제가 없습니다. –