async 모듈은 Node.js 애플리케이션에서 비동기(Asynchronous) 자바스크립트를 효율적으로 다룰 수 있도록 다양한 기능을 제공합니다. 그중 async.queue() 메서드는 큐(queue) 객체를 반환하며, 이를 활용하면 여러 작업 항목을 한 번에 동시(concurrent) 처리할 수 있습니다.
async.queue() 설치 및 사용 방법
1단계 – 아래 명령어로 Node 패키지 매니저(npm)를 초기화합니다.
npm init
2단계 – 다음 명령어로 async 모듈을 설치합니다.
npm install --save async
3단계 – 프로그램에서 아래 문장을 사용해 async 모듈을 불러옵니다.
const async = require('async')
문법(Syntax)
async.queue('function', 'concurrency value')
매개변수
위 메서드가 받는 매개변수는 다음과 같습니다.
function – 큐에 추가된 각 요소에 대해 실행될 작업 함수를 정의합니다.
concurrency value – 한 번에 동시에 처리할 요소의 개수를 지정합니다.
async.queue()는 비동기 요청을 처리하는 과정에서 활용할 수 있는 다양한 메서드와 속성을 함께 제공합니다.
push(element, callback) – 일반적인 큐처럼 요소를 큐의 끝(tail)에 추가하는 메서드입니다.
queue.push(item, callback);
length() – 현재 큐에 남아 있는 요소의 개수를 반환합니다.
queue.length()
started 속성 – 큐가 작업 처리를 시작했는지 여부를 불리언(Boolean) 값으로 반환합니다.
queue.started
unshift(element, callback) – push()와 마찬가지로 큐에 요소를 추가하지만, 차이점은 요소를 머리(head), 즉 맨 앞에 추가한다는 점입니다. 우선순위가 높은 작업을 먼저 처리하고 싶을 때 유용합니다.
queue.unshift(item, callback)
drain() 메서드 – 큐의 모든 작업이 완료되었을 때 콜백을 호출합니다. 화살표 함수(arrow function) 형태로 정의해야 동작합니다.
queue.drain(() => {
console.log("모든 작업이 완료되었습니다...");
}
pause() 메서드 – 큐에 남아 있는 나머지 요소들의 실행을 일시 중지합니다. resume()이 호출되면 처리가 다시 진행됩니다.
queue.pause()
resume() 메서드 – pause()로 일시 중지된 요소들의 실행을 재개합니다.
queue.resume()
kill() 메서드 – 큐에 남아 있는 모든 요소를 제거하고 큐를 유휴(idle) 상태로 강제 전환합니다.
queue.kill()
idle() 메서드 – 큐가 유휴 상태인지, 아니면 작업을 처리 중인지를 불리언 값으로 반환합니다.
queue.idle
예제 코드
위에서 살펴본 개념을 더 잘 이해하기 위해 실제 예제를 확인해 보겠습니다.
// async 모듈 불러오기
const async = require('async');
// 실행할 모든 작업을 담은 배열 생성
const tasks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 큐 초기화
const queue = async.queue((task, executed) => {
console.log("현재 작업 " + task + " 처리 중");
setTimeout(()=>{
// 남아 있는 작업 수 확인
const tasksRemaining = queue.length();
executed(null, {task, tasksRemaining});
}, 1000);
}, 1); // concurrency 값 = 1
// 초기에는 요소가 없으므로 큐는 유휴 상태입니다.
console.log(`큐 시작 여부 ? ${queue.started}`)
// tasks 배열의 각 작업을 큐에 추가
tasks.forEach((task)=>{
// 작업 5는 우선 처리를 위해 큐의 맨 앞에 추가
if(task == 5){
queue.unshift(task, (error, {task, tasksRemaining})=>{
if(error){
console.log(`작업 ${task} 처리 중 오류 발생`);
}else {
console.log(`작업 ${task} 처리 완료. ${tasksRemaining}개 작업 남음`);
}
})
// 작업 5를 제외한 나머지 작업은 큐의 끝에 추가
} else {
queue.push(task, (error, {task, tasksRemaining})=>{
if(error){
console.log(`작업 ${task} 처리 중 오류 발생`);
}else {
console.log(`작업 ${task} 처리 완료. ${tasksRemaining}개 작업 남음`);
}
})
}
});
// 큐의 모든 작업이 끝나면 콜백 실행
queue.drain(() => {
console.log('모든 항목이 성공적으로 처리되었습니다!');
})
// 작업 추가 후 큐 시작 여부 확인
console.log(`큐 시작 여부 ? ${queue.started}`)
실행 결과
C:\home\node>> node asyncQueue.js Queue Started ? False Queue Started ? True Currently Busy Processing Task 5 Finished processing task 5. 9 tasks remaining Currently Busy Processing Task 1 Finished processing task 1. 8 tasks remaining Currently Busy Processing Task 2 Finished processing task 2. 7 tasks remaining Currently Busy Processing Task 3 Finished processing task 3. 6 tasks remaining Currently Busy Processing Task 4 Finished processing task 4. 5 tasks remaining Currently Busy Processing Task 6 Finished processing task 6. 4 tasks remaining Currently Busy Processing Task 7 Finished processing task 7. 3 tasks remaining Currently Busy Processing Task 8 Finished processing task 8. 2 tasks remaining Currently Busy Processing Task 9 Finished processing task 9. 1 tasks remaining Currently Busy Processing Task 10 Finished processing task 10. 0 tasks remaining All items are succesfully processed !
실행 결과를 보면 concurrency 값을 1로 설정했기 때문에 작업이 하나씩 순차적으로 처리되고, unshift()로 맨 앞에 추가된 작업 5가 가장 먼저 실행된 것을 확인할 수 있습니다. 또한 모든 작업이 완료된 후 drain() 콜백이 마지막에 호출됩니다. 만약 동시 처리량을 늘리고 싶다면 concurrency 값을 조정하여 여러 작업을 병렬로 처리할 수 있습니다.