JS数组映射返回空
JS Array map returning empty
我正在尝试使用映射到 return 对象数组中的一个新字段,一旦我这样做 return 就空了。
预期结果:
[
{
"id": 2,
"name": "awesome stadium",
"opened": "1970-01-01T00:00:00.000Z",
"capacity": "39590.00",
"location": "some awesome",
"team_id": "147ff48e",
"team": {
"name": "some name",
"location": "some location"
}
}
]
代码:
const venues = await connection(VENUE_TABLE)
.limit(LIMIT_PER_PAGE)
.offset((page - 1) * LIMIT_PER_PAGE)
.select('*');
const venuesWithTeam = venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
}));
return response.json(venuesWithTeam);
我该怎么做才能让它按预期工作?
您需要在代码中使用 Promise.All
。
const venuesWithTeam = await Promise.all(venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
async
总是 return 一个 Promise,但是 .map
不会 "await" 这些 promise(它只是将它们 "as is" 放在结果中)。如果你想获得所有结果,最简单的方法是 Promise.all
:
const venuesWithTeam = await Promise.all(venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
注意:这将开始 运行并行(同时)执行所有操作,并等待所有操作都解决后再继续。如果 venues
是一个非常大的数组,它可能会导致大量连接到您的数据库并可能导致一些问题。
到运行一个接一个的请求,你将不得不循环等待前一个被解决。一种方法是使用 reduce
.
const venuesWithTeam = await venues.reduce((prom, element) => (
prom.then(async result => (
result.concat({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})
))
), Promise.resolve([]));
venues.map 将 return 一个 Promise 数组。 Promise 不会字符串化为 JSON - 好吧,它们会字符串化为 {}
因此,您必须在代码中等待 return由 .map 编辑的所有承诺
所以,Promise.all(x.map( ..... ))
即
const venuesWithTeam = await Promise.all(venues.map(async(element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
return response.json(venuesWithTeam);
或者,运行 每次迭代都是串联的而不是并行的
const venuesWithTeam = [];
for (element of venues) {
venuesWithTeam.push({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
});
}
return response.json(venuesWithTeam);
我正在尝试使用映射到 return 对象数组中的一个新字段,一旦我这样做 return 就空了。
预期结果:
[
{
"id": 2,
"name": "awesome stadium",
"opened": "1970-01-01T00:00:00.000Z",
"capacity": "39590.00",
"location": "some awesome",
"team_id": "147ff48e",
"team": {
"name": "some name",
"location": "some location"
}
}
]
代码:
const venues = await connection(VENUE_TABLE)
.limit(LIMIT_PER_PAGE)
.offset((page - 1) * LIMIT_PER_PAGE)
.select('*');
const venuesWithTeam = venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
}));
return response.json(venuesWithTeam);
我该怎么做才能让它按预期工作?
您需要在代码中使用 Promise.All
。
const venuesWithTeam = await Promise.all(venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
async
总是 return 一个 Promise,但是 .map
不会 "await" 这些 promise(它只是将它们 "as is" 放在结果中)。如果你想获得所有结果,最简单的方法是 Promise.all
:
const venuesWithTeam = await Promise.all(venues.map(async (element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
注意:这将开始 运行并行(同时)执行所有操作,并等待所有操作都解决后再继续。如果 venues
是一个非常大的数组,它可能会导致大量连接到您的数据库并可能导致一些问题。
到运行一个接一个的请求,你将不得不循环等待前一个被解决。一种方法是使用 reduce
.
const venuesWithTeam = await venues.reduce((prom, element) => (
prom.then(async result => (
result.concat({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})
))
), Promise.resolve([]));
venues.map 将 return 一个 Promise 数组。 Promise 不会字符串化为 JSON - 好吧,它们会字符串化为 {}
因此,您必须在代码中等待 return由 .map 编辑的所有承诺
所以,Promise.all(x.map( ..... ))
即
const venuesWithTeam = await Promise.all(venues.map(async(element) => ({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
})));
return response.json(venuesWithTeam);
或者,运行 每次迭代都是串联的而不是并行的
const venuesWithTeam = [];
for (element of venues) {
venuesWithTeam.push({
...element,
team: await connection('team')
.where('id', element.team_id)
.select('*')
.first(),
});
}
return response.json(venuesWithTeam);