08. TIL (callback function, promise,async)

dream.log·2021년 6월 13일
0

TIL

목록 보기
6/42
post-thumbnail

javascript의 콜백함수 개념에 대해 학습한 시간.
아직은 헷갈리는 부분도 있지만.. 열심히 공부해보자! 🔥
[드림코딩 강의를 참고하여 작성했습니다!]


1. callback function

  • 내가 전달한 것을 나중에 불러오는 함수.

    ✔️ 좀 더 고급지게 말하면?
    파라미터로 함수를 전달받아 함수의 내부에서 실행하는 함수!

  • java는 동기적이어서, hoisting이 된 이후로부터 작성된 순서로 실행된다.
    hoisting : var,function의 선언. (선언이 가장 위로 올라가는 것)
  • callback function은 arrow function으로 변환해 한줄로 표현 가능!

1) 동기 콜백과 비동기 콜백

  • 동기 콜백 (Synchronous callback) : 즉각 실행됨
    function printImmidiately(print) {
    	print();
    }
    printImmidiately(()=> console.log('hello')); ```
    
    
  • 비동기 콜백(Asynchronous callback)
    function printWithDelay(print, timeout) {
    	setTimeout(print,timeout);
    }
    printWithDelay(()=>console.log('async callback'),2000); 
  • setTimeout을 이용해 프린트 할 문구와 dalay할 시간을 지정할 수 있다. (1000초가 1초, 2000은 2초!)

2. promise

  • 비동기를 간편하게 처리할 수 있도록 도와주는 object
  • callback function 대신 사용하면 유용하나, 남발하면 콜백 지옥처럼...복잡한 코드가 될 수 있다.
  • state (상태)와 result (결과)를 파악하는 것이 중요!
  • producer와 consumer의 차이를 구분할 줄 알아야 함
  • state : pending (진행중) -> fullfilled (성공_resolve) or rejected (실패)

1) Producer

  • 새로운 promise 생성 시 자동적으로 executor가 바로 실행됨
    ex)
    const promise = new Promise ((resolve, reject) => { 
    	console.log('doing something...');
    	setTimeout(()=> {
    	resolve('dodam');
    	reject (new Error('no network'));
       // 둘 중 하나만 활성화해서 확인해보기!
    	},2000);
    });
    • 시간이 꽤 걸리는 작업. 네트워크 작업, 파일을 읽는 것 비동기로 하기
    • 하나의 함수에 성공시 송출할 결과와 실패시 송출할 결과를 모두 담아냄
    • 네트워크 요청을 사용자가 요구했을 때만 진행하면 불필요한 통신이 일어날 수 있다.

2) Consumer - then,catch,finally

  • . then
    : promise 정상적으로 수행 시,
    resolve의 값이 parameter로 전달되어 들어옴.
    같은 promise를 return하여 catch 출력도 가능. 값을 전달해도 되고 비동기인 promise를 전달해도 됨
  • . catch
    : reject 시 값을 전달함
  • .finally
    : 성공, 실패 여부와 상관없이 수행되는 함수

ex) 기본 형태

Promise
	.then((value)=> {
	console.log(value);
	})
	.catch(error =>{
		console.log(error);
	})
	.finally(()=> {
		console.log('finally');
	});

3) promise chaning

  • promise를 연결한 형태. 직접 구현해보며 개념을 확립해보자.

    ex)

    const fetchNumber = new promise ((resolve, reject =>{
    	 setTimeout (()=> resolve(1),1000);
    }));
    
    fetchNumber
    .then (num => num * 2) //2
    .then (num => num * 3) //6
    .then (num => {   //6
    	 return new promise ((resolve, reject) => {
    	 setTimeout (()=> resolve(num -1),1000); //5
    	});
    })
    .then (num => console.log(num)); //5 출력됨 ```

4) Error handling

  • promise를 활용해 에러 시 해결방법을 제안할 수 있다!

ex) 3가지의 promise return.
각 1초씩 모두 출력되려면 3초가 걸리게 지정

const getHen = () =>
 	new promise ((resolve, reject) => {
		 setTimeout(() => resolve ('닭'),1000);
	 });
const getEgg = hen =>
	new promise ((resolve,reject) =>{ 
		setTimeout(()=> resolve(`${hen} => egg`),1000);		
		setTimeout(()=> reject (new Error (`error! ${hen} => 계란 `)), 1000);
	});
const cook = egg =>
	new promise((resovle, reject) => {
		setTimeout(() => resolve (`${egg}=> fried`),1000);
	}); 

/ .then 값 지정. 생략가능한 것들 생략해 코드를 정리하고-

getHen()
	.then(hen=> getEgg(hen))   
	.then(egg => cook(egg))
	.then(meal => console.log(meal)); 

/ 계란을 송출하지 못한다면?.
상단 에러를 처리하기 위해 catch를 넣어줌

getHen() //
.then(getEgg)
.catch(error => {
	return '빵';
}) 

3. async, await

  • promise를 더 깔끔하게 정리할 수 있는 방법
  • 기본 문법
    async function 함수명 (){
    await 비동기처리메서드명 ();
    } ```

1) async
ex) 네트워크 요청이 10초 걸리는 서버가 있다고 가정하고,
promise와 async로 코드를 쓴다면?

function  fetchUser() {
	return 'dodam';
}


1) Promise 로 쓰면?

function  fetchUser() {
	return new Promise ((resolve, reject)=> { // do network request in 10secs...
		resolve ('dodam');
	});	
} 

// resolve나 reject를 쓰지 않으면 계속 pending 상태로 남아있음


2) async 사용하면?
async function fetchUser() {
	// do network request in 10secs...
		return ('dodam');
	};	

const user = fetchUser();
user.then(console.log);
console.log(user);
- fatchUser는 promise를 return한다.

2) awiat

  • async 안에서만 사용이 가능함.

ex)

function delay(ms) {
	return new Promise (resolve => setTimeout(resolve,ms));
}

async function getApple() {
	await delay (3000); // 딜레이가 끝날 때까지 기다려줌
	throw 'error';
	return 'apple';
}

async function getBanana() {
	await delay (3000);
	return 'banana';
}



1) promise를 쓴다면?
function getBanana() {
	return delay(3000)
	.then(()=> 'banana');
}


function pickFruits() {
	return getApple().then (apple => {
		return getBanana().then(banana => `${apple}+ ${banana}`);
	});
}

pickFruits().then(console.log);

2) async로 표현하면?
async function pickFruits () {
	try {
	const apple = await getApple();
	const banana = await getBanana();
	} catch {
	 return `${apple}+ ${banana}`;
}

pickFruits().then(console.log);

* 병렬로 표현하기 (기다릴 필요가 없기 때문에) 
async function pickFruits () {
	const applePromise = getApple();
	const bananaPromise = getBanana();		
	const apple = await applePromise;
	const banana = await bananaPromise;
	 return `${apple}+ ${banana}`;
}

pickFruits().then(console.log);

3) 유용한 promise APIS

  • promise all : 배열을 전달하면 병렬적으로 다 모아줌
  • promise race : 인자로 주어진 iterable의 promise 중 가장 먼저 완료되는 것과 같은 방식으로 완료되고 같은 결과값을 전달하는 promise를 반환함

    ex)
 function pickAllFruits() {
	 return Promise.all([getApple(), getBanana()]) 
	 .then(fruits => fruits.join('+')
		);
 }


 function pickOnlyOne() {
	 return Promise.race([getApple(),getBanana()]);
 }

 pickOnlyOne().then(console.log);

짚고 넘어갈 개념

  • 심화학습이 진행된 이후, promise와 async, await을 다시 깊게 공부해보자. 아직까지는 개념이 둥둥 떠 있는 느낌이니, 기초개념들부터 다시 차근차근 공부해보기 :-)
profile
한 걸음, 한 걸음 포기하지 않고 발전하는 Backend-developer 👩🏻‍💻 노션 페이지를 통한 취업 준비 기록과 회고를 진행하고 있습니다. 계획과 기록의 힘을 믿고, 실천하고자 합니다.

0개의 댓글