125*_*748 5 javascript arrays method-chaining promise
我有几个映射链,其中一个需要为每个数组元素执行数据库操作,所以我使用 async await。
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
Run Code Online (Sandbox Code Playgroud)
如果它是链中的最后一个项目,这不是问题,因为我可以用 Promise.all
console.log('results', await Promise.all(resultsAsPromises))
Run Code Online (Sandbox Code Playgroud)
但是,之后我还需要执行其他同步操作,因此我希望在继续执行下一个.map.
有没有办法做到这一点?我想也许只是制作一个提取映射器
function extractPromiseValues(value) {
return value.then(v => v);
}
Run Code Online (Sandbox Code Playgroud)
会工作,但唉,没有。
const resultsAsPromises = arr
.map(syncDouble)
.map(asyncMapper)
Run Code Online (Sandbox Code Playgroud)
不要将标识函数传递给.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));
Run Code Online (Sandbox Code Playgroud)
在您的示例的上下文中,这看起来像:
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));
Run Code Online (Sandbox Code Playgroud)
或者,如果我们将问题解释为Ghassen Louhaichi 的问题,您可以使用TC39 管道运算符 ( |>) 提案,使用以下选项之一来编写链:
const results = arr
.map(syncDouble)
.map(asyncMapper)
|> Promise.all
|> await
.map(syncCapitalize);
Run Code Online (Sandbox Code Playgroud)
const results = (arr
.map(syncDouble)
.map(asyncMapper)
|> await Promise.all(#))
.map(syncCapitalize);
Run Code Online (Sandbox Code Playgroud)
不幸的是,除非您使用Babel 插件,或者直到这些提案之一合并到官方 ECMAScript 规范中,否则您必须使用以下内容包装链await Promise.all(...):
const results = (await Promise.all(arr
.map(syncDouble)
.map(asyncMapper)))
.map(syncCapitalize);
Run Code Online (Sandbox Code Playgroud)
最后,在完整示例的上下文中:
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();Run Code Online (Sandbox Code Playgroud)