비동기 함수의 처리 결과에 대한 처리는 비동기 함수 내부에서 구현해야 하므로 함수의 매개변수로 콜백함수를 연속해서 사용하는 것을 말한다.
콜백을 연달아 사용하게 되면 코드의 가독성이 떨어진다.
firstFunc(args, function() {
secondFunc(args, function() {
thirdFunc(args, function() {
// And so on...
});
});
});
비동기 처리 상태와 처리 결과를 관리하는 객체.
인자로 resolve, reject 함수를 받는다.
let istrue = true;
const promise = new Promise((resolve, reject) => {
if(istrue) {
resolve('result')
} else {
reject('error')}
});
console.log(promise)
프로미스는 3가지 중 하나의 상태를 가진다 :
- pending: 초기 상태. 이행되거나 거절되지 않은 대기 상태라고도 불림.
- fulfilled: 실행이 성공적으로 완료된 상태
- rejected: 실행이 실패된 상태
프로미스에 이행과 거부 처리기 콜백을 추가하고, 콜백이 호출될 경우 그 반환값으로 이행하며 호출되지 않을 경우(onFulfilled, onRejected 중 상태에 맞는 콜백이 함수가 아닐 경우) 처리된 값과 상태 그대로 처리되는 새로운 프로미스를 반환합니다.
프로미스에 거부 처리기 콜백을 추가하고, 콜백이 호출될 경우 그 반환값으로 이행하며 호출되지 않을 경우, 즉 이전 프로미스가 이행하는 경우 이행한 값을 그대로 사용해 이행하는 새로운 프로미스를 반환합니다.
프로미스의 이행과 거부 여부에 상관없이 처리될 경우 항상 호출되는 처리기 콜백을 추가하고, 이행한 값 그대로 이행하는 새로운 프로미스를 반환합니다.
const myFirstPromise = new Promise((resolve, reject) => {
// 우리가 수행한 비동기 작업이 성공한 경우 resolve(...)를 호출하고,
// 실패한 경우 reject(...)를 호출합니다.
// 이 예제에서는 setTimeout()을 사용해 비동기 코드를 흉내냅니다.
// 실제로는 여기서 XHR이나 HTML5 API를 사용할 것입니다.
setTimeout( function() {
resolve("성공!") // 와! 문제 없음!
}, 250)
})
myFirstPromise.then((successMessage) => {
// successMessage는 위에서 resolve(...) 호출에 제공한 값입니다.
// 문자열이어야 하는 법은 없지만, 위에서 문자열을 줬으니 아마 문자열일 것입니다.
console.log("와! " + successMessage)
});
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 300);
});
myPromise
.then(handleFulfilledA, handleRejectedA)
.then(handleFulfilledB, handleRejectedB)
.then(handleFulfilledC, handleRejectedC);
.catch(handleRejectedAny);
// 화살표 함수 사용
myPromise
.then((value) => `${value} and bar`)
.then((value) => `${value} and bar again`)
.then((value) => `${value} and again`)
.then((value) => `${value} and again`)
.then((value) => {
console.log(value);
})
.catch((err) => {
console.error(err);
});
주어진 값으로 이행하는 Promise 객체를 반환합니다. 이때 지정한 값이 then 가능한(then 메서드를 가지는) 값인 경우, Promise.resolve()가 반환하는 프로미스는 then 메서드를 "따라가서" 자신의 최종 상태를 결정합니다. 그 외의 경우, 반환된 프로미스는 주어진 값으로 이행합니다.
어떤 값이 프로미스인지 아닌지 알 수 없는 경우, 보통 일일히 두 경우를 나눠서 처리하는 대신 Promise.resolve()로 값을 감싸서 항상 프로미스가 되도록 만든 후 작업하는 것이 좋습니다.
- resolve reject는 이미 존재하는 값을 래핑하여 프로미스를 생성하기 위해 사용한다.
// 배열을 resolve하는 프로미스를 생성
const resolvedPromise = Promise.resolve([1,2,3]);
resolvedPromise.then(console.log);
// 배열을 reject하는 프로미스를 생성
const rejectPromise = Promise.reject(new Error('Error'));
rejectPromise.catch(console.log);
주어진 모든 프로미스가 이행하거나, 한 프로미스가 거부될 때까지 대기하는 새로운 프로미스를 반환합니다.
반환하는 프로미스가 이행한다면, 매개변수로 제공한 프로미스 각각의 이행 값을 모두 모아놓은 배열로 이행합니다. 배열 요소의 순서는 매개변수에 지정한 프로미스의 순서를 유지합니다.
반환하는 프로미스가 거부된다면, 매개변수의 프로미스 중 거부된 첫 프로미스의 사유를 그대로 사용합니다.
주어진 모든 프로미스 중 하나라도 처리될 때까지 대기하는 프로미스를 반환합니다.
반환하는 프로미스가 이행한다면, 매개변수의 프로미스 중 첫 번째로 이행한 프로미스의 값으로 이행합니다.
반환하는 프로미스가 거부된다면, 매개변수의 프로미스 중 거부된 첫 프로미스의 사유를 그대로 사용합니다.
주어진 모든 프로미스가 처리(이행 또는 거부)될 때까지 대기하는 새로운 프로미스를 반환합니다.
Promise.allSettled()
가 반환하는 프로미스는 매개변수로 제공한 모든 프로미스 각각의 상태와 값(또는 거부 사유)을 모아놓은 배열로 이행합니다.
프로미스를 기반으로 동작한다. 프로미스의 후속처리 메서드에 콜백 함수를 전달해서 비동기 처리 결과를 후속 처리할 필요 없이 마치 동기적인 함수처럼 프로미스를 처리할 수 있다.
// async
async function foo(n) {return n;}
foo(1)
.then(v => console.log(v)); // 1
const baz = async n => n;
baz(3).then(v => console.log(v)); // 3
const fetch = require('node-fetch');
const getUser = async id => {
(1) const res = await fetch(`https://api.github.com/users/${id}`);
(2) const { name } = await res.json();
console.log(name);
};
getUser('aaa2');
const promise = fetch(url [, optional])
HTTP 요청 전송 기능을 제공하는 클라이언트 사이드 Web API다.
XMLHttpRequest 객체보다 사용이 편리하고 프로미스를 지원하기 때문에 콜백의 단점에서 자유롭다. fetch 함수는 HTTP 응답을 나타내는 Response 객체를 래핑한 프로미스 객체를 반환한다
fetch(url)
.then(response => {
if(!response.ok) throw new Error(response.statusText);
return response.json();
})
Axios는 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리
const axios = require('axios');
// 지정된 ID를 가진 유저에 대한 요청
axios.get('/user?ID=12345')
.then(function (response) {
// 성공 핸들링
console.log(response);
})
.catch(function (error) {
// 에러 핸들링
console.log(error);
})
.finally(function () {
// 항상 실행되는 영역
});
// 선택적으로 위의 요청은 다음과 같이 수행될 수 있습니다.
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
// 항상 실행되는 영역
});
// async/await 사용을 원한다면, 함수 외부에 `async` 키워드를 추가하세요.
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
}
}
모던 자바스크립트