문제
- 기존에 만들었던 시세표 내 border 노출은 1개 값 기준으로 되어 있었기 때문에,
rabbitMq를 통해 갑자기 여러건의 시세 변경 건이 들어온다면 바뀐 시세의 border가 잠깐 보이고 빛보다 빠르게 사라지는 문제- 즉, 현재 시세가 바뀌는 종목이 표시는 되나, 다른 종목에서 시세가 바뀌면 표시칸이 바로 바뀜
- 현재 시세칸의 border가 바로 바뀌는게 아니라 일정 시간을 두고 차례대로 없어져야함
해결방법
1. 들어온 데이터들의 종목코드를 array에 담았다가, setTimeOut으로 일정 시간 뒤에 삭제하는 방식(push & shift)
const [queue, setQueue] = React.useState<string[]>([]);
React.useEffect( () => {
// 전달 받은 시세 데이터의 종목코드를 push
setQueue(prev => {
let newArr = [...prev]
newArr.push('종목코드')
return newArr
})
// 일정 시간 뒤에 shift
setTimeout( () => {
setQueue( prev => {
let newArr = [...prev]
newArr.shift()
return newArr
})
},5000)
},['전달받은 rabbitMq의 시세 데이터'])
1-1. 1의 작업을 queue class로 구현
class Queue<T> {
items: T[] = [];
enqueue(item: T) {
this.items.push(item);
}
dequeue(): T | undefined {
if (this.isEmpty()) {
return undefined;
}
return this.items.shift();
}
isEmpty(): boolean {
return this.items.length === 0;
}
size(): number {
return this.items.length;
}
}
const initialQueue = new Queue<string>();
const [queue, setQueue] = React.useState([initialQueue]);
React.useEffect( () => {
setQueue((prevQueue) => {
const newQueue = new Queue<string>();
newQueue.items = [...prevQueue.items];
newQueue.enqueue('종목코드');
return newQueue;
});
setTimeout(() => {
setQueue((prevQueue) => {
const newQueue = new Queue<string>();
newQueue.items = [...prevQueue.items];
newQueue.dequeue();
return newQueue;
});
}, 5000);
},['전달받은 rabbitMq의 시세 데이터'])
- 여러 데이터가 짧은 시간 내에 여러건 들어오더라도 border가 갑자기 사라지지 않고 일정 시간 동안 유지된다.
- 하지만 array의 shift는 배열의 맨 앞의 값을 삭제하고 재배치 하게 되므로 시간복잡도가 O(n)이 되기 때문에, 해결해야 하는 시세 데이터가 늘어난다면 느려질 수 있다고 생각하게 됨
2. Queue 구현을 통해 시간복잡도를 낮춤
class Queue<T> {
storage = {};
front = 0;
rear = 0;
size() {
if (this.storage[this.rear] === undefined) {
return 0;
} else {
return this.rear - this.rear + 1;
}
}
add(value) {
if (this.size() === 0) {
this.storage['0'] = value;
} else {
this.rear += 1;
this.storage[this.rear] = value;
}
}
popleft() {
let temp;
if (this.front === this.rear) {
temp = this.storage[this.front];
delete this.storage[this.front];
this.front = 0;
this.rear = 0;
} else {
temp = this.storage[this.front];
delete this.storage[this.front];
this.front += 1;
}
return temp;
}
}
const initialQueue = new Queue<string>();
const [queue, setQueue] = React.useState(initialQueue);
React.useEffect( () => {
setQueue(prev => {
const newQue = new Queue<string>();
newQue.front = prev.front
newQue.rear = prev.rear
newQue.storage = {...prev.storage};
newQue.add('종목코드')
return newQue;
});
setTimeout( () => {
// queue.popleft()
setQueue(prev => {
const newQue = new Queue<string>();
newQue.front = prev.front
newQue.rear = prev.rear
newQue.storage = {...prev.storage};
newQue.popleft();
return newQue
})
}, 5000)
},['전달받은 rabbitMq의 시세 데이터'])
- queue의 storage에 종목코드를 추가/삭제 하는 방식
- 빠른 접근을 위해 front와 rear 값을 설정하고 해당 값을 storage의 key값으로 사용
* 참고 velog [자료구조] JS로 구현하는 큐 (Queue) *
'React' 카테고리의 다른 글
| [React] 'GET http://localhost:3000/User', "Uncaught SyntaxError: Unexpected token '<' " Error (0) | 2023.09.14 |
|---|---|
| [React] setState를 동기적으로 작동하게 만들기(feat. flushSync) (0) | 2023.09.08 |
| [React, TypeScript] Object is possibly 'null' (0) | 2023.09.07 |
| [React, Spring Boot] Whitelabel Error Page문제 (0) | 2023.09.07 |
| [React, TypeScript] TradingView lightweight-charts 사용 (0) | 2023.09.07 |