js

작업하던거 뒤로가기, 되돌리기 기능

개발하는 가오나시 2023. 7. 30. 22:56

요즘 매우 바쁘다. RND하던 프로젝트가 메인 프로젝트로 올라와서 정신이 없다.

 

최근에 개발한 기능은 이미지 생성을 위한 작업을 하다가 뒤로가기, 되돌리기 등의 히스토리 작업이었다.

 

가장 먼저 든 생각은 양방향 링크드 리스트 이지만, 일단 빠른 개발을 위해 배열과 포인터만 가지고 구현해보기로 했다.

 

일단 히스토리가 쌓일 배열을 하나 만든다. 그리고 현재 우리가 기억하는 히스토리의 위치를 저장하기 위해 포인터를 하나 둔다.

const history= [];
const historyPointer = 0;

이제 작업을 하게 되면 저 history배열에 들어가게 된다.

const history= [
	{
    	작업 데이터1
    },
    {
    	작업 데이터2
    },
    {
    	작업 데이터3
    },
];

이때 히스토리를 쌓는 방향을 잘 정해야한다. 일반적으로 작업된 것을 push하면 가장 최근 데이터를 배열의 마지막 아이템임으로 포인터도 같이 업데이트 해줘야한다. 하지만 히스토리를 앞에 넣는 방식으로 쌓는다면, 그럴 필요가 없다.

 

사실 어느방향이든 구현은 가능하나, 히스토리가 쌓일 때 마다 포인터가 변경될 필요는 없기 때문에 최근 데이터는 앞으로 쌓기로 하자.

const history = [newData, ...currentHistory];

그럼 이제 포인터를 움직여서 작업을 되돌아 가는 기능이다.

const go_back_work = ()=>{
	if(historyPointer === history.length - 1) return;
    
	const targetPointer = historyPointer + 1;
    
	const targetHistory = history[targetPointer];
    
	historyPointer = targetPointer;
    
	return targetHistory
}

돌아갈 포인터가 현재 히스토리의 마지막을 보고 있으면 이동을 막고, 아니라면 포인터를 업데이트 해 주고 히스토리를 돌린다. 반대로 다시 돌아가는 것도 똑같이 된다.

const go_current_work = ()=>{
	if(historyPointer === 0) return;
    
	const targetPointer = historyPointer - 1;
    
	const targetHistory = history[targetPointer];
    
	historyPointer = targetPointer;
    
	return targetHistory
}

이제 문제는 히스토리를 돌린 상태에서 작업을 하는 경우이다. 예를 들어 3번째 히스토리로 돌아가서 작업을 했으면 3번째 히스토리가 가장 최근 히스토리가 되어야한다. 포인터 또한 0이 되어야한다.

const work = (newData)=> {
	if(historyPointer !== 0) {
        const sliceHistory = history.slice(pointer, history.length);

        history = sliceHistory;
        historyPointer = 0;

        return;
    }
	...
}

물론 전역변수가 아닌 전역 상태에 저장하고 있었지만, 이런 플로우로 구현 할 수 있었다.

'js' 카테고리의 다른 글

트위치 멀티 뷰어 개발기  (1) 2023.12.21
Nestjs로 aws EC2 instance 제어하기  (1) 2023.11.27
개발에도 온고지신이 필요하다.  (0) 2023.01.13
HTML string trim() 하기  (0) 2022.12.31
ajax 요청 보내기  (0) 2022.11.21