Iterator 반복 처리

2024. 6. 24. 17:54·Web/Javascript
반응형

 

목표

Iterator 객체를 생성하고, 반복 처리에 활용한다.

 

사용이유

여러 HTTP Request를 보내서 받은 stream 데이터를 사용자 입장에서 가시적으로 확인할 수 있도록 진행바가 필요했다.

 

구현

Set을 이용한 UniqueQueue

작업이 담긴 배열을 순차적으로 진행하고 진행 중인 작업 수가 최대치일 경우 보류하여 이후에 진행되도록 작업하였다.

class Worker {
    private readonly works: Work[];
    private readonly workQueue: UniqueQueue<Work>;
    private readonly maxWorker = 60;

    constructor(requests: WorkRequest[]) {
        this.works = requests.map((r) => new Work(r));
        this.workQueue = new UniqueQueue(this.works);
    }
    
    public work(work: Work) {
    	...
    }
    
    public async run() {
        while (this.workQueue.size > 0) {
            const workingCnt = this.works.filter((work) => ...).length;

            if (workingCnt < this.maxWorker) {
                const work = this.workQueue.next();
                if (work) this.work(work);
            } else {
            	await new Promise((resolve) => setTimeout(resolve, 300));
            }
        }
    }
}

 

class UniqueQueue<T> {
    private storage: Set<T>;

    constructor(iterable?: Iterable<T> | null | undefined) {
        this.storage = new Set<T>(iterable ? iterable : undefined);
    }

    get size(): number {
        return this.storage.size;
    }

    public add(item: T) {
        if (this.storage.has(item)) {
            return;
        }
        this.storage.add(item);
    }

    public next(): T | undefined {
        const entry = this.storage.entries().next();
        if (!entry.done) {
            const value = entry.value[0];
            this.storage.delete(value);
            return value;
        } else {
            return undefined;
        }
    }
}

Iterable 객체(배열)를 받아 storage 프로퍼티에 Set<T> 생성하고, push, pop 기능을 add(push), next(pop) 메서드로 구현하였다. 기능상 문제는 없었지만, 직접 구현한 UniqueQueue 보다 배열의 Iterator 객체를 활용한 코드가 별도의 class 구현 없이 깔끔하고, 직관적일 것이라 생각되었다.

 

Iterator를 이용한 구현

class Worker {
    private readonly works: Work[];
    private readonly workIterator: Iterator<Work>;
    private readonly maxWorker = 60;

    constructor(requests: WorkRequest[]) {
        this.works = requests.map((r) => new Work(r));
        this.workIterator = this.works[Symbol.iterator]();
    }
    
    public work(work: Work) {
    	...
    }
    
    public async run() {
        let current = this.workIterator.next();
        
        while (!current.done) {
            const workingCnt = this.works.filter((work) => ...).length;

            if (workingCnt < this.maxWorker) {
            	if (current.value) {
                	this.work(current.value);
                	current = this.workIterator.next();
                }
            } else {
            	await new Promise((resolve) => setTimeout(resolve, 300));
            }
        }
    }
}

Iterable 객체(Array, String, Map, Set 등)인 배열은 iterator 객체를 반환하는 메서드인 Symbol.iterator 프로퍼티를 갖고 있다. Array[Symbol.iterator]() Symbol key를 이용하여 쉽게 Iterator 객체를 생성할 수 있다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'Web > Javascript' 카테고리의 다른 글

함수 바인딩 call, apply, bind  (1) 2025.03.06
Turborepo 모노레포 적용하기  (1) 2025.01.08
<span>,<div>에 focus 적용  (0) 2024.12.19
디바운싱(debouncing) / 쓰로틀링(throttling)  (0) 2024.11.14
Javascript 정규표현식으로 URL 찾아서 변환하기  (0) 2023.11.23
'Web/Javascript' 카테고리의 다른 글
  • Turborepo 모노레포 적용하기
  • <span>,<div>에 focus 적용
  • 디바운싱(debouncing) / 쓰로틀링(throttling)
  • Javascript 정규표현식으로 URL 찾아서 변환하기
helperwoo
helperwoo
\ೕ( ・ㅂ・)و /
  • helperwoo
    WooLog
    helperwoo
  • 전체
    오늘
    어제
    • All (52)
      • Web (25)
        • PHP (6)
        • Java (5)
        • Javascript (8)
        • Laravel (2)
        • Spring Boot (0)
        • React.js (1)
        • Electron.js (1)
        • Vue.js (1)
        • Nest.js (1)
      • Mobile (2)
        • Flutter (2)
      • DataBase (4)
        • MySQL (4)
      • Docker (6)
      • Server (5)
      • Git (2)
      • Tool (3)
      • AI (2)
      • Tip (3)
      • Log (0)
  • 블로그 메뉴

    • 링크

      • Github
    • 공지사항

    • 인기 글

    • 태그

      프로그래머스
      ignorecase
      엘리스
      MYSQL
      코드
      frankenphp
      DB연동
      Laravel
      JavaScript
      CLI
      websocket
      ollama
      flutter
      데이터베이스
      apache
      알고리즘
      with
      recursive
      nginx
      Compose
      docker
      php
      챌린지
      CTE
      http
      git
      deepseek
      dart
      image
      vscode
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    helperwoo
    Iterator 반복 처리
    상단으로

    티스토리툴바