About promise

Sasha Park·2021년 3월 16일
0

Achievement Goals

  • 어떤 경우에 중첩된 callback이 발생하는지 이해할 수 있다.
  • 중첩된 callback의 단점, Promise 의 장점을 이해할 수 있다.
  • Promise 사용 패턴과 언어적인 특징들을 이해할 수 있다.
  • resolve, reject의 의미와, then, catch와의 관계를 이해할 수 있다.
  • Promise 에서 인자를 넘기는 방법에 대해 이해할 수 있다.
  • Promise의 세가지 상태를 이해할 수 있다.
  • Promise.all 의 사용법을 이해할 수 있다.
  • async/await keyword에 대해 이해하고, 작동 원리를 이해할 수 있다.

Callback

비동기적(Async) 호출 후, 순서를 제어하기 위해서 쓰는 테크닉. 하기 코드에서는 처리완료 순서에 상관없이 A,B,C 순으로 프린트 된다. 하지만 생긴 구조가 되게 복잡해질 거 같은 느낌이다... Callback hell에 온걸 환영한다!

const printString = (string, callback) => {
	setTimeout( () => {
		callback()
    	}, Math.floor(Math.random()*100) + 1
    )
}

const printAll = () => {
	printString("A", () => {
		printString("B", () => {
			printString("C", () => {
            })
        })
    }) // 

error handling 은 다음과 같다

errorHandling ((err, data) => { //
 if (err) {
     console.log ('ERR!!');
     return;
 } 
 return data;
})

Promise

An object that is used as a placeholder for the future result of an asynchronous operation.

비동기 작업이 맞이할 미래의 완료 혹은 실패와 그 결과값을 담아낸 객체

데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜸. 이와 같은 문제점을 해결하기 위한 방법 중 하나가 promise.

function getData(callback) {
return new Promise((resolv, reject) => {
$.get('url', function(response){
resolve(response);
});
});
} // url에서 데이터를 받으면 resolve()를 호출.


getData().then(tableData => { // getData 실행 후, then() 호출 
console.log(tableData); // $.get() 으로 받는 값이 tableData에 할당. 
});

Promise의 3 status

Promise는 다음 중 하나의 상태를 가짐.

  • pending: 이행하거나 거부되지 않는 초기 상태
new Promise() // 호출 시 pending 
  • fulfilled: 연산이 성공적으로 완료됨.
function getData(){
return new Promise((resolve,reject) => {
	resolve()
})
}
getData().then(data => {
	console.log(data)
}); // resolve() 결과값을 then() 인자로 받음.
  • rejected: 연산이 실패함.
function getData(){
return new Promise((resolve,reject) => {
	reject()
})
}

getData().then().catch( err => {
	console.log(err);
}); // reject()의 결과값(error)를 catch() 인자로 받음.

getData().then( data => {
	console.log(data)
}, err => {
	console.log(err);
}); // then() 두번째 인자로 에러를 처리하는 방법. 하지만 첫번째 방법을 지향하자.

상기 내용을 종합하여 만든 promise 코드 (템플릿처럼 외울 것)

function getData(){
	return new Promise((resolve,reject) => {
	if (data){
		resolve(data);
    }
    reject(new Error("다시 해봐~"))
    });
});
}

getData().then(response => {
	console.log(response)
}).catch(error => {
	console.error(error);
}); // 서버에서 응답을 정상적으로 받아오면 resolve() method 호출, 응답이 없으면 reject() method 호출. 예를 들어 게시글에 사진자료가 깨져 있으면 reject method가 실행된 것으로 이해하자. 

Promise Chaining

여러 개의 promise를 연결하여 사용가능. 상기 코드에서 then() method를 호출하고 나면 새로운 promise 객체가 반환됨.

function getData(){
	return new Promise((resolve,reject) => {
	if (data){
		resolve(data);
    }
    reject(new Error("다시 해봐~"))
    });
});
}

getData().then(data => {
	console.log(data); // data
  	return data + 10; // ** return 값을 다음 then()으로 넘겨준다.
})
.then(data => {
	console.log(data); // data + 10
})

Promise.all()

여러 개의 promise를 동시에 실행시키고, 모든 promise가 준비될 때 쓰이는 테크닉. 보통 다수의 url에 동시에 요청을 보내고, 다운로드가 모두 완료된 후 콘텐츠를 처리할 때 사용함. Promise.all의 결과 값을 담은 배열을 반환하며, 배열 내 순서는 전달되는 순서와 연동되어 있음.

Promise.all([
  new Promise(resolve => setTimeout(() => resolve(1), 3000)),
  new Promise(resolve => setTimeout(() => resolve(2), 2000)),
  new Promise(resolve => setTimeout(() => resolve(3), 1000))
]).then(alert); // 1,2,3 반환

let names = ['sasha', 'lisa', 'coco'];
let requests = names.map(name => fetch(`http://api.github.com/users/${name}`)); //fetch를 통해 github 아이디 정보를 가져오자

Promise.all(requests)
  .then(responses => Promise.all(reponses.map(r => r.json()))) // fetch된 정보가 담긴 배열을 json() 처리하여 내용을 가공할 수 있도록 해주자.
  .then(users => users.forEach(user => alert(user.name)))
// 파싱 후 배열 users에 저장해주자.  
  

Promise.all에 전달되는 promise가 하나라도 거부되면, Promise.all은 에러와 함께 거부됨.
하기 코드에서는 두번째 promise가 거부되면서 promise.all 전체가 거부됨. 즉, 배열에 저장된 다른 promise 결과 및 이행된 promise 결과도 함께 무시.

Promise.all([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject(new Error("에러 발생!")), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).catch(alert); // Error: 에러 발생!

Reference
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
https://ko.javascript.info/promise-api

profile
'어?' 에서 '아!'가 되는 순간을 즐기는 개발자입니다.

0개의 댓글