[코캠]베이스캠프 15일차 | 마지막!!

badassong·2022년 10월 25일
0

JS

목록 보기
12/31
post-thumbnail

Today I learned!
geolocation, API, 동기와 비동기, promise객체, then(), catch(), 구조분해할당, spread 연산자, 깊은 복사, 얕은 복사, rest 파라미터

양이 많은 만큼 복습은 필수인 듯 하다.
다시 한번 정리해보자!

1. geolocation

geolocation은 현재 사용자의 위치값을 얻어올 수 있는 API이다.
여기서 API란!
어떠한 프로그램에서 제공하는 기능을 사용자가 활용할 수 있도록 만들어 둔 인터페이스이다. 요청을 받아 데이터를 가공해주는 서버에게 어떤 요청이 들어왔는지를 전달해주는 것이 바로 API인 것이다. 그리고 우리가 돌려 받게 되는 데이터를 응답(Response)이라고 한다.

2. 동기와 비동기

우리의 운영체제에게 프로세스라고 하는 작업 영역을 할당 받아 어떠한 동작을 수행한다.
코드의 실행, 프로그램의 실행, 파일 다운로드 등이 모두 프로세스별로 할당이 된다.


그리고 각 프로세스 내부에는 할당 받은 업무를 처리할 스레드가 존재한다.
스레드가 여러개라면, 하나의 프로세스 내에서 여러개의 작업을 동시에 수행할 수가 있을 것이다.

스레드가 여러개 있는 작업 환경을 멀티 스레드라고 한다. 다양한 작업을 동시간 대에 시작할 수 있다.

그리고 스레드가 각 프로세스별로 하나씩만 존재하는 경우가 있다.
이런 환경을 싱글 스레드라고 한다. 그리고 우리가 배우는 JavaScript는 싱글 스레드 기반의 언어이다.

동기, 비동기


동기란, 하나의 작업이 종료될 때까지 다음 동작은 기다리는 실행 방식을 의미한다.
비동기는 위의 예시처럼, 하나의 작업이 진행됨과 동시에 또 다른 작업도 함께 진행되는 것을 이야기한다. JavaScript는 한번에 하나의 기능만을 수행하는 싱글 스레드이기 때문에 동기적으로 동작한다.

JavaScript의 실행 환경 내부에는 call stackcallback queue라고 하는 영역이 존재한다.
해당 영역은 각각 자료구조 stack과 queue의 형태를 띄고 있다.

stack : LIFO(Last In First Out)으로 내부 데이터가 처리된다. 먼저 들어온 함수, 데이터가 가장 마지막에 처리되는 구조이다.
queue : FIFO(First In First Out)으로 내부 데이터가 처리된다. 먼저 들어온 함수, 데이터가 가장 먼저 처리되는 구조이다.

3. Promise 객체

자바스크립트는 싱글 스레드이기 때문에 한번에 하나의 동작만 수행할 수 있다.
즉, 동기적으로 동작한다.
이러한 한계점을 해결, 비동기 작업을 수행하기 위해 promise의 개념이 나타났다.
Promise는 현재는 얻을 수 없지만, 추후 작업이 완료되면 받아올 수 있는 데이터에 대한 접근 수단의 역할을 해준다.
new promise() 코드를 입력하면 Promise객체를 직접 생성해 줄 수 있는데, 이 객체는 총 세가지 상태를 갖는다.

대기(Pending) : 비동기 처리가 아직 완료되지 않은 상태
이행(Fulfilled) : 비동기 처리가 완료되어 결과값을 반환해준 상태
실패(Rejected) : 비동기 처리가 실패 혹은 오류가 발생한 상태

const promiseTest = function () {
  return new Promise((resolver, reject) => {
    setTimeout(() => {
      resolver(100);
    }, 2000);
  });
};
promiseTest()

위 코드는 promiseTest라는 함수를 실행 했을 때, 그 반환 값으로 Promise 객체를 돌려받는 코드이다.
Promise 객체를 생성할 때는 내부에 함수를 인자로 넣어줄 수 있는데, 이때 그 내부 함수는 resolver, reject를 매개변수로 받아올 수 있다.

비동기 처리가 완료되면(Fulfilled), resolver가 호출된다.
비동기 처리에 실패하면(Rejected), reject가 호출된다.

그리고 위 함수를 보면 resolver의 실행을 2초간 지연시키고 있다.

때문에 해당 Promise 객체를 돌려 받은 뒤, 2초가 지나기 이전에 참조하려 하면 Pending 상태임을 돌려받게 된다.
아직 resolver가 호출되지 않았기 때문이다.

4. then(), catch()

비동기 통신을 처리해주는 방법은 여러가지가 있는데, 그 중then(), catch() 메서드가 있다.

then()


es6 문법인 fetch()를 사용해주면 JavaScript에서 바로 통신을 수행할 수 있다.

const communicationResult = fetch(HTTP Request)
console.log(communicationResult)

하지만 위와 같이 작성하면 정상적인 응답을 받지 못한다는 것을 확인했다.
그래서 우리는 그 응답이 돌아올 때까지 기다려주어야 하는데, 이때 then() 메서드를 사용할 수 있다.

fetch(HTTP Request).then()

fetch()를 사용한 후에 그 응답을 받아올 때까지 기다리도록 fetch()에 붙여서 then()을 사용해주면 된다. then() 메서드는 fetch()뿐만 아니라 Promise 객체를 돌려주는 함수라면 언제든 사용할 수 있다. 해당 요청에 의한 통신이 완료 되었다면, then() 메서드 내부로 코드의 실행이 옮겨진다.

fetch(HTTP Request)
	.then((res) => {
		console.log(res)
	})

then() 메서드 내부에 익명 함수를 하나 만들고 그 안에서 매개변수로 데이터를 받을 수 있는데, 이 때, 받아오는 데이터가 바로 통신의 결과로 우리에게 돌려준 데이터다.
그 응답을 받아올 때까지 기다려서 정상적인 값을 받아올 수 있다.

catch()


만약 통신을 수행하다가 통신에서 문제가 생긴다면, 혹은 then() 메서드 내에서 로직을 수행하다가 에러를 만난다면 우리는 catch 메서드로 그 분기를 나눠줄 수 있다.

fetch(HTTP Request)
	.then((res) => {
		console.log(res)
	})
	.catch((err) => {
		console.error(err)
	})

이런식으로 then() 메서드 뒤에 붙여서 작성해주면 된다.
그리고 catch() 메서드 내부에도 익명 함수를 넣어줄 수 있는데, 해당 함수의 매개변수로 error의 내용을 받아올 수도 있다.

5. 구조분해할당

구조분해할당이란, 구조화 되어 있는 배열, 객체와 같은 데이터를 분해하여 각각의 변수에 다시 할당하는 것이다.

배열 구조분해할당


const arr = [ 1, 2, 3, 4, 5 ];
let [ one, two ] = arr; **// 배열의 구조분해할당**
const arr = [ 1, 2, 3, 4, 5 ];
let [ one, two ] = arr;
console.log(one, two);

이후 one과 two 변수를 참조해 보면, 배열 arr의 가장 앞의 요소부터 차례대로 숫자 1과 2가 담겨져 있는 것을 확인할 수 있다.

객체 구조분해할당


const obj = {
	name: "otter",
	gender: "male"
}

let { name, gender } = obj

배열과 같이 선언 키워드를 먼저 적어주고, 객체는 대괄호가 아닌 중괄호를 입력해서 구조분해할당을 수행한다.

let { name: a, gender: b } = obj

이렇게 해주면 각 key에 대응하는 value들이 a와 b라는 변수에 담기게 된다.

6. spread 연산자

스프레드 연산자는 하나로 뭉쳐져 있는 값들의 집합을 전개해주는 연산자이다.

const arr = [ 1, 2, 3, 4, 5 ];
console.log(...arr) // 1, 2, 3, 4, 5

전개해주고 싶은 배열의 앞에 마침표를 세개 적어주면 된다.
위와 같이 입력해주면 해당 배열의 대괄호가 벗겨지게 되는 것이다.

7. 깊은 복사, 얕은 복사

얕은 복사(shallow copy)


const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 ); // true

위의 예재처럼 객체를 직접 대입하는 경우 참조에 의한 할당이 이루어지므로 둘은 같은 데이터(주소)를 가지고 있다. 이것이 얕은 복사이다.

const obj1 = { a:1, b:2 };
const obj2 = obj1;
obj2.a = 100;
console.log( obj1.a ); // 100

위 두 객체는 같은 데이터(주소)를 가지고 있고, 그래서 같은 주소를 참조하고 있다.
때문에 obj2의 property를 수정하고, obj1를 출력해도 obj2 값과 동일하다.

깊은 복사(deep copy)


const obj1 = { a:1, b:2 };
const obj2 = { ...obj };
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1

...(spread) 연산자를 통해 { }안에 obj1의 속성을 복사하여 obj2에 할당하였다. 이제 obj1obj2는 다른 주소를 갖게되었다.

8. rest parameter

rest parmeter는 함수의 매개변수(parameter)를 배열로 전달 받는 방식이다.

const foo = function(one, two, ...arr) {
	console.log(arr)
  // rest 파라미터 또한, 매개변수이기 때문에 임의의 변수명 지정 가능
}

foo(1, 2, 3, 4, 5) // [ 3, 4, 5 ]
const foo = function(...rest) {
	console.log(rest)
}

foo(1, 2, 3, 4, 5) // [ 1, 2, 3, 4, 5 ]

위 처럼 들어오는 데이터를 전부 rest parameter로 받아올 수도 있다.

❗️ rest parameter 주의사항
rest parameter를 작성할 때는 반드시 마지막에 위치해야 합니다.

잘못된 예시

const foo = function(one, ...rest, two) {
   console.log(rest)
}
profile
프론트엔드 대장이 되어보쟈

0개의 댓글