[2024.04.26 TIL] 내일배움캠프 10일차 (알고리즘 특강, 콜백 함수, Promise)

My_Code·2024년 4월 26일
0

TIL

목록 보기
12/113
post-thumbnail

본 내용은 내일배움캠프에서 활동한 내용을 기록한 글입니다.


💻 TIL(Today I Learned)

📌 Today I Done

✏️ 알고리즘 특강 참여 (3일차)

  • 오늘은 시간복잡도, 공간복잡도, 배열, 링크드리스트를 배움

  • 다른 내용보다 링크드리스트 부분이 조금 헷갈렸음

  • 머리 속으로 개념은 잡히지만 자바스크립트로 작성하려니 막연함

  • 그래도 튜터님께서 예시 코드들을 보여주니 코드 구상이 어느정도 됨

  • 배열 : 데이터를 빈번하게 접근해야 될 때 배열을 사용

  • 링크드리스트 : 데이터를 빈번하게 삽입/삭제해야 될 때 사용

  • 다만, 위 내용은 인덱스를 모두 알 때 그렇다는 것임


  • 튜터님과 함께 진행한 코드
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

class LinkedList {
    constructor(value){
        this.head = new Node(value);
        this.nodeCount = 1;  // 총 노드의 수를 알기 위한 변수
    }
	
  	// 노드 추가하는 함수
    append(value) {
        let cur = this.head;
        while(cur.next !== null) {
            cur = cur.next;
        }

        cur.next = new Node(value);
        this.nodeCount++;
    }
}

const linked = new LinkedList(1);

linked.append(2);
linked.append(3);
linked.append(4);
linked.append(5);

  • 문제1. 원하는 위치의 노드를 찾아내는 getNode 함수 작성해보기
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

class LinkedList {
    constructor(value){
        this.head = new Node(value);
        this.nodeCount = 1;  // 총 노드의 수를 알기 위한 변수
    }
	
  	// 노드 추가하는 함수
    append(value) {
        let cur = this.head;
        while(cur.next !== null) {
            cur = cur.next;
        }

        cur.next = new Node(value);
        this.nodeCount++;
    }
  
  	getNode(index) {
      	let cur = this.head;
      	
      	for (let i = 0; i < index; i++) {
        	cur = cur.next();
        }
      	return cur
    }
}

  • 문제2. 원하는 위치에 새로운 노드를 추가하는 addNode 함수 구현해보기
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

class LinkedList {
    constructor(value){
        this.head = new Node(value);
        this.nodeCount = 1;  // 총 노드의 수를 알기 위한 변수
    }
	
  	// 노드 추가하는 함수
    append(value) {
        let cur = this.head;
        while(cur.next !== null) {
            cur = cur.next;
        }

        cur.next = new Node(value);
        this.nodeCount++;
    }
  
  	getNode(index) {
      	let cur = this.head;
      	
      	for (let i = 0; i < index; i++) {
        	cur = cur.next;
        }
      	return cur
    }
  	
  	addNode(index, value) {
    	const newNode = new Node(value);
      
      	// index가 0일 때, 즉 제일 앞에 추가할 때
      	if (index === 0) {
        	newNode.next = this.head;
          	this.head = newNode;
        	return;
        }
      
      	const prevNode = getNode(index - 1);
      	const nextNode = prevNode.next;
      
      	preNode.next = newNode;
      	newNode.next = nextNode;
      	this.nodeCount++;
    }
  
  	printNode() {
        let cur = this.head;

        while(cur) {
            console.log(cur.data);
            cur = cur.next;
        }
    }
}

const linked = new LinkedList(1);

linked.append(2);
linked.append(3);
linked.append(4);
linked.append(5);

linked.printNode();  // 1 2 3 4 5

linked.addNode(2, 5);  

console.log();
linked.printNode();  // 1 2 5 3 4 5

✏️ 자바스크립트 개인 공부 (Promise)

  • Promise를 사용하는 간단한 이유는 다음과 같음

    1. 콜백함수를 사용하다보니 비동기 동작에 대해서 콜백지옥이 발생'
    2. 콜백지옥을 해소하기 위해서 Promise라는 개념을 도입
    3. Promise는 .then() 문을 통해서 더 좋은 가독성과 유지보수를 도움
  • 일종의 콜백함수가 발전한 형태가 Promise라고 할 수 있음

  • 콜백함수 => Promise => async/await

  • Promise에 대해서 공부하기 위해 구글링을 해보니 압도적으로 setTimeout() 예제가 많았음

  • Promise가 결국 비동기 동작을 동기적으로 처리하기 위해서 사용하는데 웹에서 비동기 동작의 대표는 fetch를 통해 API에서 데이터를 가져오는 경우임

  • fetch === 시간이 걸리는 작업이기 때문에 그것도 비슷한 동작을 위해서 setTimeout() 함수를 통해 시간을 지연하는 것임

  • Promise.all( [ 함수들... ] )
    => 함수들의 실행이 모두 끝나는 것을 기다림
    => 비동기적으로 실행되기에 빨리 끝나는 함수부터 결과 출력(반환)
    => 모든 것이 끝날때가지 기다림

  • promise.race( [ 함수들... ] )
    => 마찬가지로 비동기적으로 실행
    => promise.all 과 다른 점은 가장 빨리 끝나는 함수를 기준으로 종료됨
    => 다른 함수들을 기다리지 않음

  • 아무래도 예제를 통해 코드 구조를 이해하는게 빠르기에 예제를 하나 만듦

  • 그냥 절차적으로 실행한 경우

function goToSchool() {
    console.log("학교에 갑니다.");
}

function arriveAtSchool() {
    setTimeout(() => {
        console.log("학교에 도착했습니다.");
    }, 1000)
}

function changeShoes() {
    setTimeout(() => {
        console.log("신발을 갈아신습니다.");
    }, 1000)
}

function arriveAtClass() {
    console.log("반에 도착했습니다.");
}

function takeMySeat() {
    setTimeout(() => {
        console.log("자리에 앉습니다.");
    }, 1000)
}

function study() {
    console.log("열심히 공부를 합니다.");
}

goToSchool();
arriveAtSchool();
changeShoes();
arriveAtClass();
takeMySeat();
study();

/* 출력 결과
학교에 갑니다.
반에 도착했습니다.
열심히 공부를 합니다.
학교에 도착했습니다.
신발을 갈아신습니다.
자리에 앉습니다.
*/

  • 콜백함수로만 이루어진 동기처리
function goToSchool(callback) {
    console.log("학교에 갑니다.");
    callback();
}

function arriveAtSchool(callback) {
    setTimeout(() => {
        console.log("학교에 도착했습니다.");
        callback();
    }, 1000)
}

function changeShoes(callback) {
    setTimeout(() => {
        console.log("신발을 갈아신습니다.");
        callback();
    }, 1000)
}

function arriveAtClass(callback) {
    console.log("반에 도착했습니다.");
    callback();
}

function takeMySeat(callback) {
    setTimeout(() => {
        console.log("자리에 앉습니다.");
        callback();
    }, 1000)
}

function study() {
    console.log("열심히 공부를 합니다.");
}


goToSchool(() => {
    arriveAtSchool(() => {
        changeShoes(() => {
            arriveAtClass(() => {
                takeMySeat(() => {
                    study()
                });
            });
        });
    });
});

/*
학교에 갑니다.
학교에 도착했습니다.
신발을 갈아신습니다.
반에 도착했습니다.
자리에 앉습니다.
열심히 공부를 합니다.
*/

  • Promise 객체를 통한 동기처리
function goToSchool() {
    console.log("학교에 갑니다.");
}

function arriveAtSchool() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("학교에 도착했습니다.");
            resolve();
        }, 1000)
    });
}

function changeShoes() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("신발을 갈아신습니다.");
            resolve();
        }, 1000)
    });
}

function arriveAtClass() {
    console.log("반에 도착했습니다.");
}

function takeMySeat() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("자리에 앉습니다.");
            resolve();
        }, 1000)
    });
}

function study() {
    console.log("열심히 공부를 합니다.");
}


goToSchool();  // 프로미스가 아니므로 바로 호출
arriveAtSchool()
    .then(() => {
        return changeShoes();  // 여기서 반환된 프로미스가 다음 then() 실행을 결정
    })
    .then(() => {
        arriveAtClass();  // 프로미스가 아니므로 바로 호출
        return takeMySeat();  // 여기서 반환된 프로미스가 다음 then() 실행을 결정
    })
    .then(() => {
        study();  // takeMySeat()의 결과를 기다린 후 실행
    })
    .catch((err) => {
        console.error("error");
    });

/*
학교에 갑니다.
학교에 도착했습니다.
신발을 갈아신습니다.
반에 도착했습니다.
자리에 앉습니다.
열심히 공부를 합니다.
*/


📌 Tomorrow's Goal

✏️ 개인 일정으로 인해 휴식



📌 Today's Goal I Done

✔️ 알고리즘 특강 참여

  • 오늘은 자바스크립트로 링크드리스트를 구현하는 것에 대해 배움

  • C언어의 링크드리스트의 악몽이 떠오름

  • C언어에서 구조체로 구현한 것처럼 자바스크립트에서는 클래스로 구현함

  • 구조나 개념은 같기 때문에 코드 구조를 보니 이해가 빨랐음


✔️ 자바스크립트 개인 공부 (Promise)

  • 개인 과제가 빨리 끝났기에 남은 시간은 자바스크립트 공부함

  • 그 중에서도 동기/비동기의 Promise에 대해서 공부함

  • 머리 속으로 간단한 개념만 알았지 코드에서 어떻게 쓰는지 감이 오질 않음

  • 그래도 튜터님께 질문도 하고 예제 찾아서 연습하니 조금이나마 이해함...ㅠ



⚠️ 구현 시 발생한 문제

✔️ 모듈화 시 변수가 상수로 처리됨

  • 모듈화할 때 import한 변수가 상수로 인식 됨

  • import를 사용하여 가져온 변수는 재할당할 수 없게 됨

  • 일종의 상수(const)처럼 취급됨

  • 이것은 import된 변수의 참조를 보호하기 위한 설계라고 함

  • 모듈이 외부에서 가져온 변수를 임의로 재할당하지 못하게 함으로써

  • 모듈 간의 의존성 관리가 더욱 명확해지고 안정적인 코드 작성을 도모할 수 있음

  • 그래서 나는 재할당하는 방식이 아닌 배열의 속성을 바꾸는 방법을 사용

// 기존 (import한 변수에 재할당)
movieDataList = [];


// 변경 (속성을 변경해서 배열을 비움)
movieDataList.length = 0;

// 참고 : https://kimk2062.tistory.com/24
profile
조금씩 정리하자!!!

0개의 댓글