만약 당신이 자바스크립트 개발자로 일한 지 오래되었다면, 당신은 Promise를 발견했을 것이다. 그렇지 않다면 간단한 소개를 하겠습니다.
나는 오랫동안 약속들을 다뤄왔고, 그것들이 자바스크립트에서 비동기 동작을 나타내는 좋은 방법이라고 생각한다. 이 제품들은 훌륭하지만, 여전히 우리 대부분이 알지 못하는 내장 기능들이 많이 있습니다(일주일 전까지만 해도요.
오늘 이 게시물을 통해 저는 Promise 객체의 4가지 흥미로운 빌트인 특징을 설명하고자 합니다.
먼저 데모에 사용한 유틸리티에 대해 살펴보겠습니다.
// configs for the createPromiseArrayFromConfig function
const allItemsWillResolve = [
{ settleAfterSeconds: 1, shouldReject: false },
{ settleAfterSeconds: 1, shouldReject: false },
];
const someItemsReject = [
{ settleAfterSeconds: 1, shouldReject: false },
{ settleAfterSeconds: 1, shouldReject: true },
{ settleAfterSeconds: 1, shouldReject: false },
];
const allItemsReject = [
{ settleAfterSeconds: 1, shouldReject: true },
{ settleAfterSeconds: 1, shouldReject: true }
];
const itemsWillResolveAtDifferentTime = [
{ settleAfterSeconds: 1, shouldReject: false },
{ settleAfterSeconds: 2, shouldReject: false },
];
// creates an array of promises from the provided config
function createPromiseArrayFromConfig(arrayOfConfigs) {
// map over the array config objects and return a new Promise for each item as per the config
return arrayOfConfigs.map(
({ settleAfterSeconds, shouldReject }, index) =>
new Promise((resolve, reject) => {
// wait "settleAfterSeconds" seconds before settling the promise
setTimeout(() => {
if (shouldReject) {
reject(`Item at ${index} index couldn't resolve! `);
} else {
resolve(`Item at ${index} index resolved fine!`);
}
}, settleAfterSeconds * 1000);
})
);
활용 사례에서 짐작할 수 있듯이, 각 Promise 방법을 사용하여 이 네 가지 시나리오를 실행하고 각 시나리오가 어떻게 동작하는지 살펴보겠습니다.
약속해.모두()
약속.all은 입력으로 약속의 반복을 취한 다음 입력 약속의 결과의 배열로 해결할 단일 약속을 반환합니다.
그러나 반환된 약속은 입력 배열의 단일 약속이 거부되더라도 거부됩니다. 거부 메시지/오류는 첫 번째 거부된 항목의 메시지/오류입니다.
코드를 통해 그것의 행동을 보자.
// returns an array of result, if every promise resolves otherwise throws an error from the first rejected item
async function withAll() {
const allPassing = await Promise.all(
createPromiseArrayFromConfig(allItemsWillResolve)
);
console.log(" withAll ~ allPassing", allPassing);
try {
const someFail = await Promise.all(
createPromiseArrayFromConfig(someItemsReject)
);
console.log(" withAll ~ someFail", someFail);
} catch (err) {
console.log(" withAll ~ err", err);
}
try {
const allFail = await Promise.all(createPromiseArrayFromConfig(allItemsReject));
console.log(" withAll ~ allFail", allFail);
} catch (error) {
console.error(" withAll", error);
}
const before = Date.now();
const raceCondition = await Promise.all(
createPromiseArrayFromConfig(itemsWillResolveAtDifferentTime)
);
const later = Date.now();
console.log(" withAll ~ raceCondition", raceCondition);
console.log(
"Time ~ withAll ~ raceCondition",
Math.round((later - before) / 1000),
" seconds"
);
}
위의 사진에서 볼 수 있듯이
- allItemsWillResolve 구성은 두 개의 문자열 메시지로 구성됩니다.
- 썸아이템즈구성 거부는 두 번째 약속 거부가 첫 번째 실패이므로 두 번째 약속 거부가 발생합니다.
- 올아이템즈구성 거부는 첫 번째 실패이므로 약속 거부를 통해 실패합니다.
- WillResolveAtDifferentTime 항목을 확인하는 데 2초가 걸립니다. 이는 모든 항목이 동시에 해결되기 때문이며, 약속도 마찬가지입니다.모두 배열에서 가장 긴 약속으로 해결하는 데 거의 동일한 시간이 걸립니다.
Promise를 사용하기 좋은 장소.종속적인 비동기 연산을 수행하기 위해 어레이를 매핑한 다음 Promise로 반환된 Promise 어레이를 래핑하는 것과 같은 상황이 될 수 있습니다.올 콜.
다음은 Promise의 잠재적인 사용 사례입니다."플랫폼에서 모든 이미지를 압축하고 싶은 사용자가 부분적인 데이터(예: 모든 작업이 완료되었거나 실패한 것으로 간주되지 않음)를 원하지 않는다"는 점을 고려하십시오.
여기서 작업은 서로 종속됩니다. 즉, 우리는 모든 작업/프로밋이 해결되어야만 신경쓰는데, 그 중 하나가 zip에서 누락되더라도 "우리의 작업은 불완전하기 때문입니다." 따라서 하나의 Promise를 사용하여 하는 것이 좋을 것입니다.작업이 실패하면 모두 전화를 걸어 사용자에게 오류를 표시합니다.
약속.모두 설정()
약속.Allsettled는 입력으로 약속의 반복을 받아들이고 주어진 약속이 모두 해결되거나 거부된 후에 해결되는 단일 약속을 반환하며, 각각 값이나 이유를 사용하여 각 약속의 결과를 설명하는 객체 배열이 있다.
코드를 통해 그것의 행동을 보자.
// method returns a promise that resolves after all of the given promises
// have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
async function withAllSettled() {
const allPassing = await Promise.allSettled(
createPromiseArrayFromConfig(allItemsWillResolve)
);
console.log(" withAllSettled ~ allPassing", allPassing);
try {
const someFail = await Promise.allSettled(
createPromiseArrayFromConfig(someItemsReject)
);
console.log(" withAllSettled ~ someFail", someFail);
} catch (error) {
console.error("withAllSettled", error);
}
try {
const allFail = await Promise.allSettled(
createPromiseArrayFromConfig(allItemsReject)
);
console.log(" withAllSettled ~ allFail", allFail);
} catch (error) {
console.error(" withAllSettled", error);
}
const before = Date.now();
const raceCondition = await Promise.allSettled(
createPromiseArrayFromConfig(itemsWillResolveAtDifferentTime)
);
const later = Date.now();
console.log(" withAllSettled ~ raceCondition", raceCondition);
console.log(
"Time ~ withAllSettled ~ raceCondition",
Math.round((later - before) / 1000),
" seconds"
);
}
위의 사진에서 볼 수 있듯이
- allItemsWillResolve 구성은 각각 상태와 값을 갖는 두 개체의 배열로 확인됩니다.
- 썸아이템즈Reject config는 이 시간을 거부하지 않고, 대신 3개의 개체 배열을 반환합니다. 이 중 두 번째 개체는 "rejected" 상태로 표시되고 이유는 오류 메시지로 표시됩니다. 두 번째 항목에는 키 이름의 값이 누락되어 있습니다.
- 올아이템즈Reject config는 상태가 "rejected"인 두 항목을 반환합니다.
- 항목 WillResolveAtDifferentTime은 Promise처럼 작동하므로 해결하는 데 2초가 걸립니다.모든.
Promise의 좋은 활용 사례.모두 해결되었습니다. Promise에서 사용자에게 표시합니다.(위의 모든 예), 반환된 데이터를 검토하고 개별 메시지를 표시하여 모든 파일을 압축할 수 없는 대화 상자입니다. 처음 발견한 오류만 보여줬던 이전과 비교할 때 훨씬 개선된 사용자 경험입니다.
약속해.아무나()
약속.any는 약속 배열을 입력으로 받아 배열의 약속 중 하나가 이행되는 즉시 해결되는 단일 약속 값을 반환합니다.
코드를 통해 그것의 행동을 보자.
// method returns a promise that resolves after all of the given promises
// have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.
async function withAllSettled() {
const allPassing = await Promise.allSettled(
createPromiseArrayFromConfig(allItemsWillResolve)
);
console.log(" withAllSettled ~ allPassing", allPassing);
try {
const someFail = await Promise.allSettled(
createPromiseArrayFromConfig(someItemsReject)
);
console.log(" withAllSettled ~ someFail", someFail);
} catch (error) {
console.error("withAllSettled", error);
}
try {
const allFail = await Promise.allSettled(
createPromiseArrayFromConfig(allItemsReject)
);
console.log(" withAllSettled ~ allFail", allFail);
} catch (error) {
console.error(" withAllSettled", error);
}
const before = Date.now();
const raceCondition = await Promise.allSettled(
createPromiseArrayFromConfig(itemsWillResolveAtDifferentTime)
);
const later = Date.now();
console.log(" withAllSettled ~ raceCondition", raceCondition);
console.log(
"Time ~ withAllSettled ~ raceCondition",
Math.round((later - before) / 1000),
" seconds"
);
}
위의 사진에서 볼 수 있듯이
- allItemsWillResolve 구성은 첫 번째 항목의 약속으로 결정됩니다.
- 썸아이템즈거부 구성은 첫 번째 항목의 약속으로 결정됩니다.
- 올아이템즈Reject config는 모든 약속이 거부되므로 AggregateError를 반환합니다.
- WillResolveAtDifferentTime 항목은 우리가 제공한 두 가지 약속 중 첫 번째 약속은 해결하는 데 1초밖에 걸리지 않았기 때문에 1초가 걸립니다.
Promise의 좋은 활용 사례.any는 여러 소스에서 동일한 리소스를 요청하여 처음 받은 리소스를 표시합니다. 첫 번째 지원 서비스에 고객을 연결하는 가장 좋은 방법은 모든 지원팀에 연결을 요청하고 가장 빨리 응답한 고객을 선택하는 것입니다.
약속해 인종
Promise.race는 프로미스 배열을 입력으로 받아 어레이의 프로미스 중 하나가 실행되거나 거부되는 즉시 해당 프로미스 값이나 이유를 사용하여 단일 프로미스 하나를 반환합니다.
코드를 통해 그것의 행동을 보자.
// returns a promise that fulfills or rejects
// as soon as one of the promises in an iterable fulfills or rejects
// If the iterable passed is empty, the promise returned will be forever pending.
async function withRace() {
const allPassing = await Promise.race(
createPromiseArrayFromConfig(allItemsWillResolve)
);
console.log(" withRace ~ allPassing", allPassing);
try {
const someFail = await Promise.race(
createPromiseArrayFromConfig(someItemsReject)
);
console.log(" withRace ~ someFail", someFail);
} catch (error) {
console.error(" withRace", error);
}
try {
const allFail = await Promise.race(
createPromiseArrayFromConfig(allItemsReject)
);
console.log(" withRace ~ allFail", allFail);
} catch (error) {
console.error(" withRace", error);
}
const before = Date.now();
const raceCondition = await Promise.race(
createPromiseArrayFromConfig(itemsWillResolveAtDifferentTime)
);
const later = Date.now();
console.log(" withRace ~ raceCondition", raceCondition);
console.log(
"Time ~ withRace ~ raceCondition",
Math.round((later - before) / 1000),
" seconds"
);
}
위의 사진에서 볼 수 있듯이
- allItemsWillResolve 구성은 첫 번째 항목의 약속으로 결정됩니다.
- 썸아이템즈거부 구성은 첫 번째 항목의 약속으로 결정됩니다.
- 올아이템즈Reject config는 첫 번째 약속의 거부 오류를 반환합니다.
- WillResolveAtDifferentTime 항목은 우리가 제공한 두 가지 약속 중 첫 번째 약속은 해결하는 데 1초밖에 걸리지 않았기 때문에 1초가 걸립니다.
몇 가지 중요한 점
- 지나온 것이 공허하면 돌아온 약속은 영원히 미결이다.
- 실행 가능한 값이 하나 이상 약속되지 않은 값 및/또는 이미 설정된 약속 값을 포함하는 경우 Promise.race는 실행 가능한 값 중 첫 번째로 확인됩니다.
Promise.race의 좋은 사용 사례는 주어진 작업이 x초 안에 완료되지 않을 경우 오류를 발생시키도록 연산에 대한 컷오프 타이머를 설정하는 것이다.
비디오 튜토리얼 및 예제
YouTube 비디오를 보고 실제 사례를 볼 수도 있습니다.
당신은 또한 여기에서 코드샌드박스를 가지고 포크하고 놀 수 있습니다.
이 게시물이 당신에게 도움이 되었기를 바랍니다. 의견이나 질문이 있으시면 언제든지 아래 코멘트에 올려주세요. 저는 그것들을 듣고 작업하고 싶습니다.
그런 게시물들을 더 보려면 저를 @sun_anshuman 팔로우해주세요.
사용된 리소스
저는 이 게시물에 대한 연구를 하면서 MDN 문서를 팔로우했습니다.
2022년 1월 10일 https://dev.to에서 처음 출판되었다.
'javascript' 카테고리의 다른 글
플랫아이언 스쿨 소프트웨어 엔지니어링 1단계 완료! — 내 프로젝트 (1) | 2022.01.11 |
---|---|
Nullish 병합 연산자(?) (0) | 2022.01.11 |
用javascript學習演算法和資料結構(5) (0) | 2022.01.11 |
Javascript의 O.O. (0) | 2022.01.11 |
Apaitu Async Waiting, Promise, Callback — Handling Asyncronus javascript #1. (0) | 2022.01.11 |
댓글