본문 바로가기

코드스테이츠 SEB FE 41기/Section 별 내용 정리

section2/unit3/[JS/Node] 비동기(9/26)

반응형

블로깅 주제

  • 비동기

1. 지금 현재, 당신의 기분이나 느낌을 표현해 주세요.

  • 월요일...실화냐!!! ㅠㅠ 벌써 9월의 마지막 주이다. 오늘부터 다음주 수요일까지는 헬게이트(?) 일 것 같다. 비동기라는 개념 자체가 처음이라 낯선데 비동기 끝나자마자 리엑트라니...대망의 리액트!! 제발 제발 제발 잘 이해하고 잘 넘어갔으면 좋겠다 ㅠㅠ 이번주 화이팅이다...

2. 오늘 무엇을 학습한 내용 중 지금 떠올릴 수 있는 단어를 모두 나열해 주세요.

  • 비동기

3. 2에서 작성한 단어를 가지고, 오늘의 학습 내용을 설명해 보세요.

- 과제: part1 타이머 API 개요

▶ Promise 실행 함수가 가지고 있는 두 개의 파라미터 resolve 와 reject 는 각각 무엇을 의미하나요?

  • resolve(value)
    일이 성공적으로 끝난 경우, 그 결과를 나타내는 value와 함께 호출.
    state는 pending에서 fulfilled로, result는 value가 된다.
  • reject(error)
    에러 발생 시 에러 객체를 나타내는 error와 함께 호출.
    state는 pending에서 rejected로, result는 error가 된다.

 

resolve, reject함수에는 전달인자를 넘길 수 있습니다. 이때 넘기는 전달인자는 어떻게 사용할 수 있나요?

1. resolve

function getData() {
  return new Promise(function(resolve, reject) {
    var data = 100;
    resolve(data);
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});

2. reject

function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error("Request is failed"));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

 

자바스크립트 Promise 쉽게 이해하기

(중급) 자바스크립트 입문자를 위한 Promise 설명. 쉽게 알아보는 자바스크립트 Promise 개념, 사용법, 예제 코드. 예제로 알아보는 then(), catch() 활용법

joshua1988.github.io


new Promise()를 통해 생성한 Promise 인스턴스에는 어떤 메서드가 존재하나요? 각각은 어떤 용도인가요?

1. then()

then은 Promise에서 활용하는 가장 기본적인 메서드이다.

const promise = new Promise((resolve, reject)=>{
    resolve('성공시 반환하는 값');
})

promise
    .then(successReturn => {alert(successReturn)});

then 메서드는 resolve 함수가 실행될 경우 실행되고, resolve 함수에 인자로 넘겨준 값이 넘어오게 된다.
.then의 첫 번째 아규먼트는 Promise가 이행되었을 때 실행되는 함수이고, 여기서 실행 결과를 받는다.
.then의 두 번째 아규먼트는 Promise가 거부되었을 때 실행되는 함수이고, 여기서 에러를 받는다.
작업이 성공적으로 처리된 경우만 다루고 싶다면, 두번째 인수를 생략하고 하나만 전달하면 된다.

위와같은 코드에서는 successReturn으로 '성공시 반환하는 값'이 넘어왔으며, 이 값을 alert할 것이다.

 

2. catch()

const promise = new Promise((resolve, reject)=>{
    reject(new Error("에러 발생!"));
})

promise
    .catch(errorReturn => {alert(errorReturn)});

catch메서드는 reject 함수가 실행될 경우 실행되고, reject함수에 인자로 넘겨준 값이 넘어오게 된다.
.catch의 아규먼트는 Promise가 거부되었을 때 실행되는 함수이고, 여기서 에러를 받는다.
.then에서 첫번째 아규먼트에 null을 넣고, 두번째 아규먼트를 활용하는 방법 (.then(null, 실행함수)) 과 동일한데, 문법이 단순하고 가독성이 높다는 장점이 있다.

 

3. finally()

promise의 성공, 실패 여부와 상관없이 promise의 처리가 완료되면 실행된다.
또한, finally 핸들러는 자동으로 다음 핸들러에 결과와 에러를 전달하기 때문에 다음과 같이 활용할 수도 있다.

const promise = new Promise((resolve, reject) => {
    resolve('성공시 반환하는 값');
})

promise
    .finally(() => alert("프라미스가 준비되었습니다."))
    .then(result => alert(result));

 

4. all()

all() 은 파라미터로 여러 개의 promise 객체가 담긴 Array와 같이 순회 가능한 객체를 받아온다. 
전달인자로 받아온 순회 가능한 객체에 주어진 모든 Promise가 이행한 후, 혹은 Promise가 주어지지 않았을 때 이행하는 Promise를 반환한다.

모든 promise가 fulfilled 되면 결과를 배열로 반환하고 하나라도 reject된 경우 그 이유를 반환한다.
주어진 Promise 중 하나가 거부하는 경우, 첫 번째로 거절한 Promise의 이유를 사용해 자신도 거부한다.

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});

// > Array [3, 42, "foo"]

 

5. race()

race()도 all()과 마찬가지로 promise 객체가 담긴 Array와 같이 순회가능한 객체를 받아온다.
순회 가능한 객체 내부의 promise객체들 중 가장 먼저 완료된 Promise객체를 반환한다.

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // Both resolve, but promise2 is faster
});
// > "two"

위와 같이 먼저 실행이 완료되는 promise2의 객체를 반환하고, .then을 통해 해당 객체의 이행결과에 따른 행위를 수행한다.

https://velog.io/@sukong/JS-Promise-%EA%B0%9D%EC%B2%B4%EC%99%80-%EB%A9%94%EC%84%9C%EB%93%9C

 

[JS] Promise 객체와 메서드

js에서 비동기처리를 위해 활용하는 Promise객체의 활용방법과 메서드를 공부해보았습니다 🤗

velog.io


▶ Promise의 세 가지 상태는 각각 무엇이며, 어떤 의미를 가지나요?

new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
  • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태 <- resolve 실행
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태 <- reject 실행

 

 await 키워드 다음에 등장하는 함수 실행은 어떤 타입을 리턴할 경우에만 의미가 있나요?

Promise 타입

await 은 Promise 가 fulfill 되거나 reject 될 때까지 async 함수의 실행을 일시정지 하고, fulfill 되면 async 함수를 일시정지한 부분부터 실행한다.

 

 await 키워드를 사용할 경우, 어떤 값이 리턴되나요?

Promise resolve 값


- Node.js

자바스크립트는 브라우저에서 사용된다.

브라우저 밖에서 자바스크립트 사용할 수 있도록 하는 툴이 Node.js이다. 서버를 만드는데 많이 쓰인다. 

 

※ 모듈이란?

건축으로부터 비롯된 모듈이라는 단어는, 어떤 기능을 조립할 수 있는 형태로 만든 부분이다.

그 중 fs(File System) 모듈은, PC의 파일을 읽거나 저장하는 등의 일을 할 수 있게 도와준다.

 

Node.js 내장 모듈을 사용하는 방법

Node.js 에서는 JavaScript 코드 가장 상단에 require 구문을 이용하여 다른 파일을 불러온다.

const fs = require('fs'); // 파일 시스템 모듈을 불러옵니다
const dns = require('dns'); // DNS 모듈을 불러옵니다

// 이제 fs.readFile 메서드 등을 사용할 수 있습니다!

 

 3rd-party 모듈을 사용하는 방법

서드 파티 모듈(3rd-party module): 해당 프로그래밍 언어에서 공식적으로 제공하는 빌트인 모듈(built-in module)이 아닌 모든 외부 모듈

ex) Node.js에서 underscoreNode.js 공식 문서에 없는 모듈이기 때문에 서드 파티 모듈이다.

서드 파티 모듈을 다운로드하기 위해서는 npm을 사용해야 한다.

npm install underscore
const _ = require('underscore');

 

Node.js 공식 문서 가이드

ex)

▷ fs.readFile(path[, options], callback)

메서드 fs.readFile 은 로컬에 존재하는 파일을 읽어온다.

메서드 fs.readFile비동기적으로 파일 내용 전체를 읽는다. 이 메서드를 실행할 때에는 전달인자 세 개를 받는다.

 

  • path \<string> | \<Buffer> | \<URL> | \<integer>

path에는 파일 이름을 전달인자로 받는다. 네 가지 종류의 타입을 넘길 수 있지만 일반적으로 문자열(<string>)의 타입을 받는다.

다음은 `'etc/passwd' 라는 파일을 불러오는 예제이다.

fs.readFile('/etc/passwd', ..., ...)

 

  • options \<Object> | \<string>

대괄호로 감싼 두 번째 전달인자 options는 넣을 수도 있고, 넣지 않을 수도 있다. 대괄호는 선택적 전달인자를 의미한다.

options는 문자열 또는 객체 형태로 받을 수 있다.

문자열로 전달할 경우 인코딩을 받는다.

 'utf8' 을 두 번째 전달인자로 받는 것을 확인할 수 있다.

// /etc/passwd 파일을 'utf8'을 사용하여 읽습니다.
fs.readFile('/etc/passwd', 'utf8', ...);

options를 객체 형태로 받는 것을 확인할 수 있다.

let options = {
  encoding: 'utf8', // utf8 인코딩 방식으로 엽니다
  flag: 'r' // 읽기 위해 엽니다
}

// /etc/passwd 파일을 options를 사용하여 읽습니다.
fs.readFile('/etc/passwd', options, ...) 

 

  • callback \<Function>
    • err \<Error> | \<AggregateError>
    • data \<string> | \<Buffer>

콜백 함수를 전달한다. 파일을 읽고 난 후에 비동기적으로 실행되는 함수이다.

콜백 함수에는 두 가지 매개변수가 존재한다.

에러가 발생하지 않으면 err 는 null 이 되며, data 에 문자열이나 Buffer 라는 객체가 전달된다. data 는 파일의 내용이다.

질문: data 에는 문자열이나 Buffer 가 전달됩니다. 어떤 경우에 문자열로 전달되는 것일까요?

→ If no encoding is specified, then the raw buffer is returned ==> encoding이 주어졌을 때

 

const fs = require('fs');
fs.readFile(__dirname+'/test.txt', 'utf8', (err, data) => {
    if (err) {
      throw err; // 에러를 던집니다.
    }
    console.log(data);
  });

hihello 출력됨

const fs = require('fs');
fs.readFile(__dirname+'/test.txt', (err, data) => {
    if (err) {
      throw err; // 에러를 던집니다.
    }
    console.log(data);
  });
 <Buffer 68 69 68 65 6c 6c 6f> 출력됨

- 과제: part2 fs 모듈

JSON.parse(): JSON 문자열을 JavaScript 객체로 변환

JSON.stringfy()(문자열 형태)된 데이터를 자바스크립트에서 사용할 수 있도록 바꿔준다.

parse() 메서드는 JSON 문자열을 인자로 받고 결과값으로 JavaScript 객체를 반환한다.

https://www.daleseo.com/js-json/

 

JSON.parse()와 JSON.stringify()

Engineering Blog by Dale Seo

www.daleseo.com


1. callBack

const getDataFromFile = function (filePath, callback) {
  // TODO: fs.readFile을 이용해 작성합니다
  fs.readFile(filePath, 'utf-8', (err, data) => {
    if(err) callback(err, null); //에러이면 콜백의 첫번째인자에 err를 넣어준다.
    else callback(null, data); //에러가 아니면 콜백의 두번째 인자에 data를 넣어준다.
  })
};

utf-8 -> 컴퓨터가 정보를 읽는 규칙(utf8로 써도 인식됨)

 

2. promiseConstructor

const getDataFromFilePromise = filePath => {
  // return new Promise()
  // TODO: Promise 및 fs.readFile을 이용해 작성합니다.
  return new Promise(function(resolve,reject){
    fs.readFile(filePath, 'utf-8', (err, data) => {
      if(err) reject(err);
      else resolve(data);      
    })
  });
};

 

3. basicChaining

const readAllUsersChaining = () => {
  // TODO: 여러개의 Promise를 then으로 연결하여 작성합니다
  return getDataFromFilePromise(user1Path)
  .then((data) => JSON.parse(data))
  .then((user1) => {
  // user1,user2 데이터를 함께 배열에 넣기 위해 하나의 스코프 안에 써줌-> user1에 접근 가능하도록
    return getDataFromFilePromise(user2Path) 
    .then((data) => JSON.parse(data))
    .then((user2) => {
      return [user1, user2];
      //.then((user2) =>  [user1, user2];) 도 됨. =>가 return 역할
    })
  })
}

then 안에 있는 데이터를 밖으로 빼서 사용할 수 있을까?

==> await 사용하면 됨. 대신 데이터가 많을 경우 시간이 오래걸리므로 await를 너무 남발하면 안됨

 

4. promiseAll : 여러 개의 promise 한번에 처리. 빠르게 비동기적 처리 가능.

const readAllUsers = () => {
  // TODO: Promise.all을 이용해 작성합니다
  const promise1 = getDataFromFilePromise(user1Path);
  const promise2 = getDataFromFilePromise(user2Path);
  return Promise.all([promise1,promise2])
  .then((values) => {
    return values.map(el => JSON.parse(el));
    // values 전체를 JSON.Parse(values)로 넣으면 안됨. JSON.parse()는 JSON 문자열을 JavaScript 객체로 변환
  })
}

구조분해할당 사용ver

 

5. async/await

const readAllUsersAsyncAwait = async() => {
  // TODO: async/await 키워드를 이용해 작성합니다
  const user1 = await getDataFromFilePromise(user1Path);
  const user2 = await getDataFromFilePromise(user2Path);

  return [JSON.parse(user1),JSON.parse(user2)]
}

질문

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});

// > Array [3, 42, "foo"]

 Promise.all 의 전달인자는 어떤 형태인가요?

배열 속에 promise들이 포함된 형태

 Promise.all 을 사용할 경우에 then 메서드의 매개변수는 어떠한 형태인가요?

결과가 배열로 반환된다.

 Promise.all 에 두 개의 Promise 요청이 전달되고, 만일 그 중 하나가 rejected 상태가 되는 경우, then 메서드, catch 메서드 중 어떤 메서드를 따라갈까요?

Promise.all() 함수는 주어진 promise를 실행하다가 reject 되는 것이 하나라도 있으면 즉시 실행을 멈춘다.

즉, catch 메서드를 따라간다.

 

반응형