질문
여러 맵 체인이 있으며 그중 하나는 각 배열 요소에 대해 데이터베이스 작업을 수행해야하므로 async await를 사용하고 있습니다.
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
Promise.all
로 풀 수 있기 때문에 체인의 마지막 항목이라면 문제가되지 않습니다.
console.log('results', await Promise.all(resultsAsPromises))
그러나 나중에 수행해야하는 다른 동기 작업이 있으므로 다음 .map
으로 이동하기 전에 프라 미스의 값을 풀고 싶습니다.
이 작업을 수행하는 방법이 있습니까? 추출 매퍼를 다음과 같이 만드는 것으로 생각했습니다.
function extractPromiseValues(value) {
return value.then(v => v);
}
작동하지만 안타깝게도 아닙니다.
var arr = [1, 2, 3, 4, 5];
function timeout(i) {
return new Promise((resolve) => {
setTimeout(() => {
return resolve(`number is ${i}`);
}, 1);
});
}
function syncDouble(i) {
return i * 2;
}
async function asyncMapper(i) {
return await timeout(i)
}
function extractPromiseValues(value) {
return value.then(v => v);
}
async function main() {
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
// .map(extractPromiseValues)
console.log('results', await Promise.all(resultsAsPromises))
}
main();
배열 메서드 체인 내에서 Promise 배열을 어떻게 풀 수 있습니까?
답변1
식별 함수를 .then ()
에 전달하는 대신 동기 작업을 전달하거나 전달하기 전에 async
함수에서 Promise을 기다립니다
. 동기 작업에 :
function syncCapitalize(s) {
return s.slice(0, 1).toUpperCase() + s.slice(1);
}
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
.map(p => p.then(syncCapitalize)); // OR
//.map(async p => syncCapitalize(await p));
예제의 맥락에서 이것은 다음과 같습니다.
function timeout(i) {
return new Promise(resolve => {
setTimeout(() => {
resolve(`number is ${i}`);
}, 1);
});
}
function syncDouble(i) {
return i * 2;
}
function asyncMapper(i) {
return timeout(i);
}
function syncCapitalize(s) {
return s.slice(0, 1).toUpperCase() + s.slice(1);
}
async function main() {
const arr = [1, 2, 3, 4, 5];
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
.map(p => p.then(syncCapitalize)); // OR
//.map(async p => syncCapitalize(await p));
console.log('results', await Promise.all(resultsAsPromises));
}
main();
또는 질문을 Ghassen Louhaichi가 가지고있는 것으로 해석하는 경우 TC39 파이프 라인 연산자 (| >
) 제안 이하:
const results = arr
.map(syncDouble)
.map(asyncMapper)
|> Promise.all
|> await
.map(syncCapitalize);
const results = (arr
.map(syncDouble)
.map(asyncMapper)
|> await Promise.all(#))
.map(syncCapitalize);
불행히도 Babel 플러그인 을 사용하지 않는 이상 이러한 제안 중 하나가 공식 ECMAScript 사양에 병합되었습니다. 체인을 await Promise.all (...)
으로 래핑해야합니다.
const results = (await Promise.all(arr
.map(syncDouble)
.map(asyncMapper)))
.map(syncCapitalize);
마지막으로 전체 예제의 맥락에서 :
function timeout(i) {
return new Promise(resolve => {
setTimeout(() => {
resolve(`number is ${i}`);
}, 1);
});
}
function syncDouble(i) {
return i * 2;
}
function asyncMapper(i) {
return timeout(i);
}
function syncCapitalize(s) {
return s.slice(0, 1).toUpperCase() + s.slice(1);
}
async function main() {
const arr = [1, 2, 3, 4, 5];
const results = (await Promise.all(arr
.map(syncDouble)
.map(asyncMapper)))
.map(syncCapitalize);
console.log('results', results);
}
main();
출처 : https://stackoverflow.com/questions/62939432/how-can-i-unwrap-an-array-of-promises-within-a-chain-of-array-methods