비동기2 - 실습

jeongjwon·2023년 3월 20일
0

SEB FE

목록 보기
23/56

🧩 [과제] 타이머 API

callback 함수

Promise

Async & Await



⭐️ CHECK ⭐️

① Promise 실행 함수가 가지고 있는 두 개의 파라미터 resolve 와 reject

  • resolve : 콜백함수가 성공적으로 처리시 함수 호출
  • reject : 콜백함수가 성공적으로 처리를 못할 시 함수 호출

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

  • resolve 로 넘긴 전달인자는 .then 메서드를 이용한다.

  • reject 로 넘긴 전달인자는 .catch 메서드를 이용한다.

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

  • promise의 내부 프로퍼티 state, result 에 직접 접근을 할 수가 없으므로 .then , .catch, .finally 후속 처리 메서드를 이용하여 접근할 수 있다. 각각의 후속 처리 메서드가 실행되면 promise 객체를 리턴한다.

    • .then 메서드는 콜백함수가 성공적으로 처리 시 실행
    • .catch 메서드는 콜백함수가 실패적으로 처리 시 실행
    • .finally 메서드는 콜백함수의 실행 성공 여부에 관계없이 실행

④ Promise의 세 가지 상태(states)

  • pedning 대기 : 비동기 처리 로직이 아직 완료되지 않은 상태 , fulfilled 과 rejected 가 아닌 상태 (= 기본 상태이자 new Promise() 메서드 호출시)
  • fulfilled 이행 : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태 , promise 가 성공적일 때 ( pending 에서 콜백함수의 처리가 성공적일 때 = resolve )
  • rejected 거부 : 비동기 처리가 실패하거단 오류가 발생한 상태, promise 가 실패적일 때 ( pending 에서 콜백함수의 처리가 실패할 때 = reject )

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

  • 해당 함수가 Promise 타입을 리턴한 경우에만 의미가 있다.

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

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

  • await 키워드는 async 키워드가 붙어있는 함수 내부에서만 사용할 수 있으며, 비동기 함수가 리턴하는 Promise로 부터 result 값을 추출해준다.

  • 즉, await 키워드를 사용하면 일반 비동기처럼 바로 실행이 다음 라인으로 넘어가는 것이 아니라 결과값을 얻을 수 있을 때까지 기다려 준다.

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

  • 여러 개의 비동기 작업을 동시에 처리하고 싶을 때 사용하므로 순회 가능한 객체에 주어져야 한다. 즉, 전달인자는 Promise 가 담겨 있는 배열 등의 이터러블(iterable)의 형태여야 한다.

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

  • then 메서드는 콜백함수의 실행이 정상적으로 처리되었다는 것이다.
  • promise.all 의 첫번째 promise 가 가장 늦게 이행되더라도 처리 결과는 배열의 첫번째 요소로 저장이 된ㄷ. 요소 전체가 promise 인 배열을 받고 새로운 promise 를 반환한다.

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

  • 배열 내 요소 중 어느 하나라도 거부하면 즉시 거부된다. 즉 에러를 처리하는 catch 메서드를 실행한다.



📌 Node.js

Node.js 내장 모듈(File System)을 사용하기 위함

  • html - <script src="불러오고_싶은_스크립트.js"></script>
    • readFile 메서드 : 파일을 읽을 때
    • writeFile 메서드 : 파일을 저장할 때
  • js - require(다른 파일명) 다른 파일을 불러옴
  • 써드 파티 모듈을 사용하기 위해 underscore 를 설치(npm install underscore), require 구문을 이용해 사용 가능

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

로컬에 존재하는 파일을 비동기적으로 읽어옴

  • path : \<string> | \<Buffer> | \<URL> | \<integer>
  • options : \<Object> | \<string> 문자열일 경우 인코딩
  • callback : 파일을 읽고 난 후 비동기적으로 실행할 콜백함수, 전달인자로는 err 와 data
    • 에러가 발생하면 err 를 throw 하고 data 를 전달하지 않는다.
    • 에러가 발생하지 않으면 err 는 null 이 되고 data 에 문자열이나 Buffer 객체인 파일의 내용이 전달된다.
fs.readFile(filePath, 'utf9' , (err, data)=>{
	if(err){
    	callback(err, null);
    }else{
      callback(null, data);
    }
}



🧩 [과제] fs 모듈

callBack

비동기처리
① fs.readFile 이용하여 callback 이 실행되어야 한다.
② 에러가 발생할 경우, callback의 첫번째 인자에 에러 객체가 전달되어야 한다.
③ callback 두번째 인자에 파일 내용이 전달되어야 한다.

//파일로 부터 데이터를 읽어옴
const fs = require("fs");
function getDataFromFile = function(filePath, callback){
  	fs.readFile(filePath, 'utf8', (err, data)=>{
      
    	if(err) callback(err, null);
      	else callback(null, data);
    });
}
getDataFromFile('README.md', (err, data) => console.log(data));

promise

① Promise 형태로 리턴되어야 한다.
② then 블록을 통하여 파일 내용이 전달되어야 한다.
③ 에러가 발생할 경우, catch 블록을 통하여 에러 객체가 전달되어야 한다.

const fs = require("fs");
const getDataFromFilePromise = filePath => {
	return new Promise((resolve, reject)=>{
      fs,readFile(filePath, 'ut8', (err,data)=>{
        if(err){ 
          reject(err); 
        }
        //에러발생 시 reject 함수 호출 
        else { 
          resolve(data); 
        } 
        //콜백함수의 성공적 처리 후 resolve 함수 호출
      });
    }
}
getDataFromFilePromise('README.md')
	.then(data => console.log(data)); //resolve 호출시 then 메서드로 , 반환값은 string 형태
  	.catch(err => console.log(err)); //reject 호출시 catch 메서드로

chaining

① 체이닝의 결과가 Promise 형태로 리턴되어야 한다.
② user1.json의 내용과 user2.json 내용을 합쳐 배열로 리턴되어야 한다.
③ fs module 을 직접 사용하지 말고, getDataFromFilePromise 을 두 번 사용해야 한다.
④ Promise.all 또는 async/await 을 사용하지 않고 풀어야 한다.

const path = require('path');
const { getDataFromFilePromise } = require('./02_promiseConstructor');

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const readAllUsersChaining = () => {
  
  return getDataFromFilePromise(user1Path).then((user1) => {
  //user1Path 파일에서 데이터를 가져옴
  	return getDataFromFilePromise(user2Path).then((user2) =>{	
    //위의 then 리턴값이 user2Path 파일에서 데어터를 가져오는 것이므로
    //전달인자 data 는 user2Path의 데이터
      
      const user1Data = JSON.parse(user1);                          
      const user2Data = JSON.parse(user2);
                             
      return [user1Data, user2Data];                          
    });
  });
}      
readAllUsersChaining();

promise.all

① Promise 형태로 리턴되어야 한다.
② Promise.all 을 사용해서 풀어야 한다.
③ user1.json의 내용과 user2.json 내용을 합쳐 객체로 리턴되어야 한다.

const { rejects } = require('assert');
const { resolve } = require('path');
const path = require('path');
const { getDataFromFilePromise } = require('./02_promiseConstructor');

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const readAllUsers = () => {
  // getDataFromFilePromise 의 반환값은 object
  const promise1 = getDataFromFilePromise(user1Path);
  const promise2 = getDataFromFilePromise(user2Path);
  
  return Promise.all([promise1, promise2])
  		.then(([user1, user2]) => {
    	 //각각의 promise1, promise2 는 
    	//user1Path와 user2Path 로부터 받아온 JSON 문자열을 반환
    	
    	const user1Data = JSON.parse(user1);
    	const user2Data = JSON.parse(user2);
    
    	return [user1Data, user2Data];
    	//JSON 문자열을 다시 객체 형식으로 변환시켜 배열형태의 Promise 로 리턴
  });
  
 
  
  readAllUsers();
  

Async/Await

① async 키워드를 사용한 함수는 AsyncFunction의 인스턴스이다.
② await 키워드만 이용해 배열이 리턴되어야 한다.
③ user1.json의 내용과 user2.json 내용을 합쳐 배열로 리턴되어야 한다.

const path = require('path');
const { getDataFromFilePromise } = require('./02_promiseConstructor');

const user1Path = path.join(__dirname, 'files/user1.json');
const user2Path = path.join(__dirname, 'files/user2.json');

const readAllUsersAsyncAwait = async () => {
  
  let user1Data = JSON.parse(await getDataFromFilePromise(user1Path));
  let user2Data = JSON.parse(await getDataFromFilePromise(user2Path));

  return [user1Data, user2Data];
}

0개의 댓글