如何在数组方法链中解包 Promise 数组?
How Can I Unwrap an Array of Promises within a Chain of Array Methods?
我有几个映射链,其中一个需要为每个数组元素执行数据库操作,所以我使用异步等待。
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
如果它是链中的最后一项,这不是问题,因为我可以用 Promise.all
展开它
console.log('results', await Promise.all(resultsAsPromises))
但是,之后我还需要执行其他同步操作,所以我想在继续下一个 .map
.
之前解开 promise 的值
有办法吗?我想也许只是制作一个像
这样的提取映射器
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 数组
不是将身份函数传递给 .then()
,而是传递您的同步操作,或者 await
async
函数中的承诺,然后再传递给您的同步操作:
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();
或者,如果我们将问题解释为 , you could use the TC39 pipeline operator (|>
) proposal 使用以下选项之一编写链:
F# Pipelines Proposal
const results = arr
.map(syncDouble)
.map(asyncMapper)
|> Promise.all
|> await
.map(syncCapitalize);
Smart Pipelines Proposal
const results = (arr
.map(syncDouble)
.map(asyncMapper)
|> await Promise.all(#))
.map(syncCapitalize);
不幸的是,除非您使用的是 Babel plugin,或者在这些提案之一被合并到官方 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();
我有几个映射链,其中一个需要为每个数组元素执行数据库操作,所以我使用异步等待。
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 数组
不是将身份函数传递给 .then()
,而是传递您的同步操作,或者 await
async
函数中的承诺,然后再传递给您的同步操作:
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();
或者,如果我们将问题解释为 |>
) proposal 使用以下选项之一编写链:
F# Pipelines Proposal
const results = arr
.map(syncDouble)
.map(asyncMapper)
|> Promise.all
|> await
.map(syncCapitalize);
Smart Pipelines Proposal
const results = (arr
.map(syncDouble)
.map(asyncMapper)
|> await Promise.all(#))
.map(syncCapitalize);
不幸的是,除非您使用的是 Babel plugin,或者在这些提案之一被合并到官方 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();