asynchronous operation (비동기 처리)은 다른 작업이 완수되는 동안 다른 일로 넘어가는 것
예를 들면 network request나 querying a database 같이 시간이 걸리는 작업들을 기다리지 않고 다음 코드를 실행하는 것이다.
Promise는 비동기 처리의 결과를 나타내는 객체
프로미스의 상태에는 다음 세가지가 존재할 수 있음
대기 Pending : 초기 상태 - 비동기 처리가 아직 안 끝남
이행 Fulfilled : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
거부 Rejected : 비동기 처리가 실패한 상태
프로미스가 더 이상 대기 상태가 아니라면 확정(settled)되었다고 한다.
그 상태는 이행(Fulfilled)이거나 거부(Rejected) 둘 중 하나임.
const executorFunction = (resolve, reject) => { };
const myFirstPromise = new Promise(executorFunction);
Promise의 생성자(constructor)는 executor function을 파라미터로 가진다.
executor function은 비동기 처리를 시작하고 프로미스가 어떻게 확정되어야 하는지 나타낸다.
그리고 resolve()와 reject() 함수 두 가지를 가진다. 이것들은 프로그래머가 정의하는 것이 아니라 자바스크립트가 고유의 함수를 파라미터로 전달한다.
resolve : 인자 하나를 가지는 함수. resolve가 호출되면 프로미스의 상태를 pending에서 fulfilled로 바꿈. 프로미스의 resolved value는 resolve에 인자로 전달된 값으로 확정됨.
reject : reason이나 error를 인자로 가지는 함수. 호출되면 프로미스의 상태는 pending에서 rejected로 바꿈. 그리고 전달받은 인자를 rejection reason으로 설정함.
setTimeout()은 Node API이다. 어떤 작업을 일정 시간이 지난 후 실행하게 만든다.
콜백함수와 딜레이 되는 시간(밀리초)을 파라미터로 가진다.
const delayedHello = () => {
console.log('Hi! This is an asynchronous greeting!');
};
setTimeout(delayedHello, 2000);
이렇게 코드를 작성하면 적어도 2초 후에 콜백함수가 호출된다.
적어도라고 한 이유는 자바스크립트가 비동기 처리를 할 때는 바로 실행가능한 다른 코드를 먼처 실행하기 때문이다. 만약에 본문에 다른 코드가 포함되어있다면 그 코드를 먼저 실행하고 delayedHello 함수를 호출하느라 2초 이상 걸릴 수도 있다. (이런 걸 이벤트 루프라고 하는 듯)
~비동기적 프로미스를 만드는 법~
const returnPromiseFunction = () => {
return new Promise((resolve, reject) => {
setTimeout(( ) => {resolve('I resolved!')}, 1000);
});
};
const prom = returnPromiseFunction();
연습으로 작성한 코드
console.log("This is the first line of code in app.js.");
const usingSTO = () => console.log('Yay! Coding is so fun!!');
setTimeout(usingSTO, 2000);
console.log("This is the last line of code in app.js.");
출력 결과 (usingSTO함수가 늦게 호출됨)
프로미스 객체의 상태가 결정되면 그 다음으로 해야할 일을 결정하는 함수
higher-order-function 이다
두 개의 콜백 함수를 인자로 가짐
이 콜백함수들을 핸들러(handler)라고 함
프로미스의 상태에 따라 적절한 핸들러가 호출됨
성공시 호출되는 핸들러를 onFulfilled 실패시 호출되는 핸들러를 onRejected라고 하기도함
한 가지 중요한 .then()의 특징은 항상 프로미스를 리턴한다는 것
잘못된 핸들러가 제공된다면 .then()은 확정값이 같은 프로미스를 리턴함
let prom = new Promise((resolve, reject) => {
let num = Math.random();
if (num < .5 ){
resolve('Yay!');
} else {
reject('Ohhh noooo!');
}
});
const handleSuccess = (resolvedValue) => {
console.log(resolvedValue);
};
const handleFailure = (rejectionReason) => {
console.log(rejectionReason);
};
prom.then(handleSuccess, handleFailure);
프로미스 상태가 fulfilled가 되면 handleSuccess가 실행되고 rejected가 되면 handleFailure를 호출한다.
코드의 가독성을 위해 다음과 같이 resolved 부분과 rejection 부분을 나눠서 쓸 수 있음
적절한 핸들러가 주어지지 않으면 확정값이 동일한 프로미스를 리턴하는 걸 이용한 것
prom
.then((resolvedValue) => {
console.log(resolvedValue);
})
.then(null, (rejectionReason) => {
console.log(rejectionReason);
});
이를 더 보기좋게 만들려면 catch()함수를 쓰면 된다
prom
.then((resolvedValue) => {
console.log(resolvedValue);
})
.catch((rejectionReason) => {
console.log(rejectionReason);
});
catch()는 하나의 인자만 갖는다.
프로미스를 연쇄적으로 실행하는 것
각 처리 과정이 서로에게 의존적이거나 실행 순서가 중요할 때 쓰면 좋음
firstPromiseFunction()
.then((firstResolveVal) => {
return secondPromiseFunction(firstResolveVal);
})
.then((secondResolveVal) => {
console.log(secondResolveVal);
});
프로미스를 실행 👉 첫번째 then 실행 👉 두번째 프로미스 리턴 👉 두번째then실행 👉최종 결과값 콘솔에 출력
연습문제
const {checkInventory, processPayment, shipOrder} = require('./library.js');
const order = {
items: [['sunglasses', 1], ['bags', 2]],
giftcardBalance: 79.82
};
checkInventory(order)
.then((resolvedValueArray) => {
return processPayment(resolvedValueArray);
})
.then((resolvedValueArray) => {
return shipOrder(resolvedValueArray);
})
.then((successMessage) => {
console.log(successMessage);
})
.catch((errorMessage) => {
console.log(errorMessage);
});
함수 이름들을 보면 짐작이 가듯이 재고를 확인하고 👉 재고가 있으면 결제로 넘어가고 👉 올바른 결제 정보가 입력됐으면 배송 절차 👉 절차가 완료됐으면 successMessage 표시, 아니면 errorMesage 표시
대강 이런식으로 사용된다는 거
복수의 프로미스를 순서 상관없이 가능한 효율적으로 실행하는 것 (concurrency; 동시성)
프로미스들의 배열을 인자로 받고 하나의 프로미스를 리턴한다.
리턴되는 프로미스의 상태가 결정되는 방법은 다음과 같다.
모든 배열의 프로미스가 이행 상태면(resolve), Promise.all()이 리턴하는 프로미스는 이행 상태가 되며 각 프로미스들의 resolve value를 배열로 갖게 된다
어떤 배열의 프로미스가 실패 상태면(reject), Promise.all()이 리턴하는 프로미스는 그 즉시 실패 상태가 되며 해당 프로미스의 rejection reason을 갖게 된다. 👉이런걸 failing fast 라고 부름
let myPromises = Promise.all([returnsPromOne(), returnsPromTwo(), returnsPromThree()]);
myPromises
.then((arrayOfValues) => {
console.log(arrayOfValues);
})
.catch((rejectionReason) => {
console.log(rejectionReason);
});
코드카데미 자바스크립트 class 연습문제 Find Your Hat (0) | 2020.10.14 |
---|---|
코드카데미 Javascript - Async Await (0) | 2020.10.12 |
코드카데미 Javascript - 모듈 내보내기 가져오기 (export, import) (0) | 2020.09.29 |
코드카데미 Javascript - 브라우저 호환성과 Babel을 이용한 버전 변환 (0) | 2020.09.28 |
코드카데미 Javascript - 클래스와 인스턴스, 상속, 정적 메소드 (0) | 2020.09.27 |
댓글 영역