단일 스레드이기 때문에 node.js에서는 실제로 병렬이 아닙니다. 그러나 여러 이벤트를 예약하고 미리 결정할 수없는 순서대로 실행할 수 있습니다. 그리고 데이터베이스 액세스와 같은 일부는 데이터베이스 쿼리 자체가 별도의 스레드에서 실행되지만 완료되면 이벤트 스트림에 다시 통합된다는 점에서 실제로 "병렬"입니다.
그렇다면 여러 이벤트 핸들러에서 콜백을 어떻게 예약합니까? 글쎄, 이것은 브라우저 측 자바 스크립트의 애니메이션에서 사용되는 일반적인 기술 중 하나입니다. 변수를 사용하여 완료를 추적하십시오.
이것은 해킹처럼 들리며 그것은 잠재적으로 지저분하게 들리며 추적을 수행하는 데 많은 전역 변수를 남기고 더 적은 언어로 될 것입니다. 하지만 자바 스크립트에서는 클로저를 사용할 수 있습니다.
function fork (async_calls, shared_callback) {
var counter = async_calls.length;
var callback = function () {
counter --;
if (counter == 0) {
shared_callback()
}
}
for (var i=0;i<async_calls.length;i++) {
async_calls[i](callback);
}
}
fork([A,B,C],D);
위의 예에서는 비동기 및 콜백 함수에 인수가 필요하지 않다고 가정하여 코드를 단순하게 유지합니다. 물론 코드를 수정하여 비동기 함수에 인수를 전달하고 콜백 함수가 결과를 누적하여 shared_callback 함수에 전달하도록 할 수 있습니다.
추가 답변 :
실제로,이 fork()
함수는 이미 클로저를 사용하여 비동기 함수에 인수를 전달할 수 있습니다.
fork([
function(callback){ A(1,2,callback) },
function(callback){ B(1,callback) },
function(callback){ C(1,2,callback) }
],D);
남은 일은 A, B, C의 결과를 모아 D에게 전달하는 것뿐입니다.
더 많은 추가 답변 :
나는 저항 할 수 없었다. 아침 식사 중에 계속 생각했습니다. 다음은 fork()
결과를 누적 하는 구현입니다 (일반적으로 콜백 함수에 인수로 전달됨).
function fork (async_calls, shared_callback) {
var counter = async_calls.length;
var all_results = [];
function makeCallback (index) {
return function () {
counter --;
var results = [];
for (var i=0;i<arguments.length;i++) {
results.push(arguments[i]);
}
all_results[index] = results;
if (counter == 0) {
shared_callback(all_results);
}
}
}
for (var i=0;i<async_calls.length;i++) {
async_calls[i](makeCallback(i));
}
}
그것은 충분히 쉬웠습니다. 이것은 fork()
상당히 일반적인 용도로 사용되며 여러 비 동종 이벤트를 동기화하는 데 사용할 수 있습니다.
Node.js에서의 사용 예 :
function A (c){ fs.readFile('file1',c) };
function B (c){ fs.readFile('file2',c) };
function C (c){ fs.readFile('file3',c) };
function D (result) {
file1data = result[0][1];
file2data = result[1][1];
file3data = result[2][1];
}
fork([A,B,C],D);
최신 정보
이 코드는 async.js 또는 다양한 promise 기반 라이브러리와 같은 라이브러리가 존재하기 전에 작성되었습니다. 나는 async.js가 이것에 의해 영감을 받았다고 믿고 싶지만 증거가 없습니다. 어쨌든 .. 오늘 이것을 할 생각이라면 async.js 또는 promise를 살펴보십시오. async.parallel과 같은 것이 어떻게 작동하는지에 대한 좋은 설명 / 그림 위의 대답을 고려하십시오.
완전성을 위해 다음은 사용 방법입니다 async.parallel
.
var async = require('async');
async.parallel([A,B,C],D);
위에서 구현 한 함수 async.parallel
와 정확히 동일 하게 작동합니다 fork
. 가장 큰 차이점은 D
node.js 규칙에 따라 첫 번째 인수로 오류를 전달 하고 두 번째 인수로 콜백을 전달한다는 것 입니다.
promise를 사용하여 다음과 같이 작성합니다.
Promise.all([A,B,C]).then(D);