JavaScript는 싱글 스레드로 동시 작업이 안되는데 예를 들어 Network 통신이나 파일 읽기 등
무거운 작업을 수행할 때 JS는 결과값이 반환될 때까지 계속 기다리게된다.
만약 페이지가 출력이 되야하는데 그 이전 단계인 파일 읽기가 10초가 걸린다면 그 시간동안 페이지는 출력이 안되고 백지상태로 있을 것이다.
그렇기 때문에 이때는 promise로 비동기 처리를 해줘야한다.
promise란, 비동기를 간편하게 처리해주는 Javascript 내장 객체이며
아래와 같이 상태와 단계가 나누어진다.
Producer에서는 promise 객체를 생성하여 결과를 반환해준다.
promise는 클래스이므로 아래와 같이 new로 객체를 생성하고
인자로 executor 콜백함수를 전달 받는다.
이 때 executor는 resolve, reject를 전달 받는다.const promise = new Promise((resolve, reject) => {})
아래는 setTimeout 이라는 브라우저 API를 콜백함수로 전달한 예제이다.
const promise = new Promise((resolve, reject) => { setTimeout(() => // 성공적인 promise 수행 완료 시 아래 resolve 실행 resolve('ellie') // Error()는 에러 발생 시 에러는 나타내는 JS에서 제공하는 오브젝트 // reject(new Error('no network')) ,1000) })
Cosumer에서는 then, catch, finally를 이용하여 값을 받아올 수 있다.
promise // promise가 정상적으로 수행되었다면 resolve에서 받은 값이 value에 전달된다. .then((value) => { console.log(value) }) // promise에서 오류 발생 시 에러 출력 .catch(error => { console.log(error) }) .finally(() => { // 성공, 실패 상관없이 실행되는 코드 console.log('finally') })
promise chaining이란 여러개의 promise 객체를 연결하여 사용하는 것이다.
then() 메서드를 호출 시 또 다른 promise 객체가 반환된다.
fetchNumber 라는 promise 객체를 새로 만들어주자.
setTimeout 콜백 함수를 인자로 넘어주었고 성공 시 1이라는 값이 반환된다.const fetchNumber = new Promise((resolve, reject) => { setTimeout(() => {resolve(1)}, 1000) } )
생성한 promise 객체의 then 메소드를 호출한다.
fetchNumber //num 변수에 위 코드에서 반환한 1이 할당되고 곱하기 2를 해준다. .then(num => num * 2) // 2 // 위에서 반환된 값이 아래 num에 할당되어 곱하기 3를 한 후 num에 다시 전달한다. .then(num => num * 3) // 6 // then은 값을 전달하지만 promise도 전달할 수 있다. .then(num => { return new Promise((resolve, reject) => { setTimeout(() => resolve(num - 1), 1000) // 5 }) }) // 최종 num의 값을 콘솔로 출력한다. .then(num => console.log(num)) // 5
promise 사용 중 에러 발생 시 에러를 출력하는 방법도 있지만
promise chaining이 끊김없이 계속 이어질 수 있도록 대체 값을 반환할 수도 있다.
Producer
const getHen = () => new Promise((resolve, reject) => { setTimeout(() => resolve('닭'), 1000) }) const getEgg = hen => new Promise((resolve, reject) => { 에러 발생!! setTimeout(() => reject(new Error(`error! ${hen} => egg`)), 1000) //setTimeout(() => resolve(`${hen} => egg `), 1000) }) const cook = egg => new Promise((resolve, reject) => { setTimeout(() => resolve(`${egg} => fries `), 1000) })
Consumer
getHen() // getHen()에서 전달받은 닭을 이용해서 getEgg에 전달 .then(hen => getEgg(hen)) // getEgg에서 에러 발생 시 'bread'를 대신 반환함으로서 chain이 끊기지않고 // 다음 프로미스 객체로 전달된다. .catch(error => { return 'bread' }) // getEgg()에서 전달받은 달걀을 이용해서 cook에 전달 .then(egg => cook(egg)) .then(meal => console.log(meal))
이 모든 예제는 유튜브 드림코딩 엘리님의 가르침을 참고하였다.
출처 : 갓엘리님의 드림코딩 - 자바스크립트 프로미스 개념편