Coding/Today I Learned (148)

07
29

그래요. Async와 Await는 어디에나 있어요. 그래서 엄.청.중.요.합.니.다

1. 왜 씁니까?

  • promise를 조금 더 깔끔하고 더 동기적으로 보이게끔 만든다.
  • 콜백 함수나 promise가 너무 많으면 코드를 읽기 너무 힘들다. 그저 promise에 요소를 조금 더 해서 사용하는 'syntactic sugar'이 된다!

2. 어떻게 사용하나요?

//! promise Ver.
function findUser() {
	return new Promise((resolve, reject) => {
		// 뭔가 통신을 한다던지 지연이 일어난다.
        resolve('Hendrix');
	});
}

const user = findUser();
user.then(console.log);
console.log(user)

//! async Ver.
async function findUser() {
		// 뭔가 통신을 한다던지 지연이 일어난다.
        return 'Hendrix';
}

const user = findUser();
user.then(console.log);
console.log(user)

 

  • 물론 둘의 결과는 똑같다. 그저 promise를 줄여서 async로 퉁 친 것이다. 하지만 가끔은 promise가 필요할 때가 있다. 마치 for... 과 while처럼 말이다.
function delay(el) {
	return new Promise(resolve => setTimeout(resolve, el));
}

async function beatIt() {
	await delay(1000);
    return 'Oh No...Help';
}

async function defense() {
	await delay(2000);
    return 'Miss!';
}
  • await은 setTimeout에 의해 소괄호에 적힌 시간에 맞게 기다렸다가 리턴하게 된다.
  • 이외에 promise.all이나  then으로 연결할 수 있는 부분은 다른 포스팅에서 정리하는 것이 좋을 것 같다.
COMMENT
 
07
27

Pinkie Promises! 올바르게 작동하거나 문제가 생겼을때 이렇게 하자는 '약속'같은 느낌이다.

1. Promise를 왜 쓰는가?

  • 비동기 함수들을 사용할 때 콜백 함수를 너무 많이 사용하면 복잡해서 읽기가 매우 힘들다.
  • 그래서 자바스크립트 내장 메서드 'promise'를 쓴다.

2. Producer

const proise = new Promise((resolve, reject) => {
	console.log('Doing Someting');
    setTimeout(() => {
		resolve('name')
    	reject(new Error('No Name'))
    }, 2000);
});
  • Promise는 class다. 그래서 일단 new를 사용해 만들게 된다.
  • resolve는 기능이 정상적으로 돌아가 마지막에 리턴할 함수 => 위의 예시에서 보이듯이 알맞은 인자를 전달해 준다.
  • reject는 기능이 돌아가다가 뭔가 오류가 생겼을 때 리턴할 함수

3. Consumers

  • 위에서 만들어 놓은 promise를 이용하는 방법이 된다.
promise
	.then((value) => {
		console.log(value); // name
	})
    .catch(error => {
		console.log(error)
    })
    .finally(() => {
		console.log('End')
	});
  • 위의 예시에서 then은 기능이 올바르게 작동한다면 나오게 될 기능을 하게 된다. 이때, value는 우리가 promise에서 resolve라는 콜백 함수로 전달한 값인 'name'이 전달되게 된다.
  • 만약 문제가 생긴다면? reject로 준 Error가 발생한다.
  • 문제가 발생해서  reject 콜백 함수가 사용되면, then이 promise를 다시 불러오게 되고, 그 불러온  promise에 catch를 다시 등록시키게 된다. 그러면 에러가 발생했을 때, 그것을 다시 잡아와 catch안에서 사용하게 된다. 이를 '체이닝'이라고 한다.
  • finally는 가장 마지막에 에러가 발생하든, 올바르게 실행되든 상관없이 실행된다.

4. fs.readFile()

  • 비동기적으로 파일을 읽어 온다는 의미이다.
fs.readFile('읽어올 파일의 경로', 'utf8(옵션, 대부분 utf8)', (err, data) => {
	if(err) {
		throw err; // 문제가 있다면 err를 던진다!
	}
	console.log(data); // 문제가 없다면 콘솔에 data를 입력한다.
})
  • 파일의 불러올 방식으로는 주로, 'utf8'이 사용된다. 사람이 읽을 수 있는 언어로 만들어주는 느낌이다.
  • 콜백 함수에서 err가 발생하지 않으면 자동으로 null이 되며, data에 내용이 전달된다.
COMMENT
 
07
27

같이 알바하는 동기가 일을 동기적으로 하면...? 더이상 동기사랑은 어렵게 된다.

1. 사건의 발단.

 나는 다양한 알바와 일들을 했었다. 카페부터 고깃집, 건축, 상하차, 대학 사무실 등 다양한 일들을 하며 많은 동기들을 만났다. 그럴 때마다 함께 일하는 친구들을 분석하곤 했다. 정말 다양한 사람들이 있었다. 어떤 사람은 일을 똑바로 가르쳐 주지 않아도 주어진 시간에 안에 완벽히 수행해 내고, 어떤 사람들은 정해진 시간도 모자라서 몇 명의 인원이 도움을 줘야 겨우 일을 마치는 그런 친구들도 있었다. 그런 친구들의 주된 특징은 '비효율'적인 행동에 있다.

 

2. 동기

  • 코드가 적혀있는 순서대로 실행된다.
  • 그래서 하나의 코드가 끝나기 전에 다음 코드는 실행되지 않는다.
  • 위의 비효율적인 일을 하는 친구들이 하는 행동과 같다.
  • 예를 들어, 오븐에 빵을 넣고 구워지는 동안 설거지라도 할 수 있지만, 그렇지 않고 오븐 앞에서 빵을 지키고 있다가, 다 되면 서빙을 하고 난 후에 돌아와 다른 일을 한다.

3. 비동기

  • 꼭 코드가 적혀있는 순서대로는 실행되지 않는다.
  • 그래서 코드가 실행되는 도중 먼저 필요한 코드를 실행하고 중간에 다른 코드를 실행하며 알맞은 일을 할 수 있다.
  • 효율적으로 일을 하는 친구들에 해당된다.
  • 예를 들어, 오븐에 빵을 넣어놓고 온도와 타이머를 정확히 맞춰 놓고 빵이 타이머가 울리기 전에, 설거지도 하고, 시간이 남아 바닥도 한번 쓸고, 손도 씻고 난 후에 타이머가 완료된 빵을 가지고 서빙을 하는 것이다.
  • 여러 가지 스레드가 돌아간다고 생각할 수 있다. 너무 느린 속도를 가진 일을 다른 스레드에서 실행하게 해 두고 그 보다 빠른 일을 막히지 않게 끝내는 것이다.

4. 자바스크립트의 비동기

  • 자바스크립트는 싱글 스레드를 가진다. 그렇다면 어떻게 비동기적으로 코드를 실행시킬 수 있을까?
  • '콜백 함수'를 사용한다.
    • 함수는 스택 형태로 사용되지만, 큐 형태로 사용해야 맞다. 하지만 웹 API가 시간을 처리하는 요소들을 담당하기 때문에 가능하다.
    • 그렇게 비동기 요소는 따로 처리되어 태스크 큐에 저장되고, 콜백 함수들을 받아 실행시킨다.
  • 결국은 콜백 지옥이 되고 말 것이다.

5. Promise

  • 콜백 지옥을 막기 위해서 ES6 이상부터 사용 가능한 함수
  • 첫 번째 인자로 수행할 비동기 작업, 두 번째 인자로 콜백 함수에 전달하는 함수를 넣는다.
  • 이를 체이닝 방식으로 비동기 작업을 순서대로 적어 보기 쉽게 작성 가능하다.

6. Async & Await

  • promise보다 더 직관적으로 함수를 실행할 수 있게 한다.
  • 비동기 함수 앞에 async를 적으면 동기 작업처럼 비동기 함수를 작성할 수 있다.
  • 이후 비동기 함수로 조회된 데이터를 변수에 할당할 때도 await을 적어서 멈추게 할 수 있다. 마지막 변수에만 await을 안 적으면 그것부터 위로 실행되게 될 것이다.

 

COMMENT
 
07
25

이런 그래프를 코드로 작성 한다면 어떻게 될까? 

1. Graph

  • 우리가 생각하는 그 그래프가 맞다.
  • 하지만 이것을 코드로, 그리고 글로 작성한다는 것을 생각해 보면 된다.

2. Graph에서 사용하는 용어

  • 정점(vertex) : 그래프에서 볼 수 있는 하나의 점
  • 간선(edge) : 연결된 선
  • 무(방)향 그래프(undirected graph) : 서로 연결되어 있어서 서로가 서로에게 접근이 가능한 그래프.
  • 단방향 그래프(directed graph) : 한쪽에서만 연결되어 있는 그래프
  • 진입 차수(in degree)와 진출 차수(out degree) : 몇 개의 간선으로 들어오고 몇 개의 간선으로 나가는지
  • 인접(adjacency) : 정점들 사이에 아무것도 없고 서로 한 번에 간선으로 연결된 경우
  • 자기 루프(self loop) : 간선이 진출되어 다시 자신에게 돌아오는 경우
  • 사이클(cycle) : 다시 돌아서 각각의 정점들을 거쳐 자신으로 돌아오는 형태의 그래프

3. Tree

  • 나무를 뒤집어 놓은것 처럼 계층으로 나누어 뻗어나가는 그래프
  • 토너먼트 대진표 같은 모양을 생각하면 된다.

4. Tree에서 사용하는 용어

  • 노드(Node) : 각각 하나의 요소에 해당하는 데이터
  • 루트(Root) : 트리의 시작점이 되는 노드
  • 부모 노드(parent node) : 부모가 되는 상위의 노드
  • 자식 노드(child node) : 자식이 되는 하위의 노드
  • 리프(leaf) : 더 이상 자식이 없는 끝이 되는 노드

5. Binary Search Tree

  • 트리는 자료를 탐색할때 사용할 수 도 있다.
  • 이때, 처음 루트에서 두 가지 노드로 빠져나오는 형태를 가진 이진트리(Binary Tree)를 대표적으로 사용할 수 있다.
아무리 자료구조를 안다고 해도 알고리즘 문제를 풀기는 쉽지 않았다.
그래서 가장 처음으로 다시 돌아가서 용어 정리부터 다시 시작해본다.
COMMENT