Promise.all(iterable)
완료된는 순서가 상관없는 여러개의 promise를 비동기적으로 실행하고, 결과값을 한번에 받는 함수
let urls = [
'https://api.github.com/users/iliakan',
'https://api.github.com/users/Violet-Bora-Lee',
'https://api.github.com/users/jeresig'
];
// fetch를 사용해 url을 프라미스로 매핑합니다.
let requests = urls.map(url => fetch(url));
// Promise.all은 모든 작업이 이행될 때까지 기다립니다.
Promise.all(requests)
.then(responses => responses.forEach(
response => alert(`${response.url}: ${response.status}`)
));
fetch 예시
let names = ['iliakan', 'Violet-Bora-Lee', 'jeresig'];
let requests = names.map(name => fetch(`https://api.github.com/users/${name}`));
Promise.all(requests)
.then(responses => {
// 모든 응답이 성공적으로 이행되었습니다.
for(let response of responses) {
alert(`${response.url}: ${response.status}`); // 모든 url의 응답코드가 200입니다.
}
return responses;
})
// 응답 메시지가 담긴 배열을 response.json()로 매핑해, 내용을 읽습니다.
.then(responses => Promise.all(responses.map(r => r.json())))
// JSON 형태의 응답 메시지는 파싱 되어 배열 'users'에 저장됩니다.
.then(users => users.forEach(user => alert(user.name)));
all 은 전달된 프로미스중 하나라도 거부되면 모두 거부처리된다.
또한 Promise.all(interable) 로써 이터러블객체를 받는데, 프로미스가 아닌 객체일때는 그대로 결과에 담긴다.
Promise.allSettled(iterable)
all과 동일하지만, 성공과 실패의 여부에 따라서, 결과값을 온전히 보존한다.
let urls = [
'https://api.github.com/users/iliakan',
'https://api.github.com/users/Violet-Bora-Lee',
'https://no-such-url'
];
Promise.allSettled(urls.map(url => fetch(url)))
.then(results => { // (*)
results.forEach((result, num) => {
if (result.status == "fulfilled") {
alert(`${urls[num]}: ${result.value.status}`);
}
if (result.status == "rejected") {
alert(`${urls[num]}: ${result.reason}`);
}
});
});
[
{status: 'fulfilled', value: ...응답...},
{status: 'fulfilled', value: ...응답...},
{status: 'rejected', reason: ...에러 객체...}
]
Promise.race(iterable)
all 과 동일하지만, 가장먼저 완료된 결과(혹은에러)를 반환한다
Promise.race([
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))
]).then(alert); // 1
Promise.resolve(value)
결과값을 프로미스를 반환하도록 할 때 사용한다.
예를들면 캐싱을 사용할 때, 기존함수는 프로스를 반환한다고하면,
캐싱된 값을 프로미스로 변환 시켜서 반환해야 일관성이 유지된다.
let cache = new Map();
function loadCached(url) {
if (cache.has(url)) {
return Promise.resolve(cache.get(url)); // (*)
}
return fetch(url)
.then(response => response.text())
.then(text => {
cache.set(url,text);
return text;
});
}
Promise.reject(error)
resolve와 동일한 메커니즘으로 에러를 프로미스로 반환할 때 사용한다.
callback기반의 함수를 promise화 하기
오래된 라이브러리는 promise방식으로 사용되지 않은 것들이있고,
그것을 promise로 바꾸는것은 그렇렇게어렵지 않다.
function loadScript(src, callback) {
let script = document.createElement("script");
script.src = src;
script.onload = () => callback(null, script);
script.onerror = () =>
callback(new Error(`${src}를 불러오는 도중에 에러가 발생함`));
document.head.append(script);
}
let loadPromise = function (src) {
return new Promise((resolve, reject) => {
loadScript(src, (error, script) => {
if (err) {
reject(err);
} else {
resolve(script);
}
});
});
};
하지만 콜백함수를 여러번 호출하는 경우라면 변경할 수 없다. promise는 resolve, reject 중 하나가 호출되면 그대로 끝이기 때문이다.
콜백을 단 한번만 호출하는 경우에만 적용할 수 있다.
반응형
'Archive' 카테고리의 다른 글
JS 모듈 (0) | 2022.09.04 |
---|---|
제너레이터 (0) | 2022.09.04 |
try ... catch 와 에러 핸들링 (0) | 2022.09.04 |
내장 클래스 확장하기 (0) | 2022.09.03 |
class의 정적 메서드, 정적 프로퍼티 (0) | 2022.09.03 |