处理 Node.js 中的嵌套 forEach
Dealing with nested forEach in Node.js
我正在做一些需要嵌套 foreach 循环来处理一些数据的事情。
目的是我需要查找一个 ID 数组,每个 ID 都与一个用户相关,我只需要从 API 调用的响应中提取他们的名字。服务 A 有 ID 列表,然后针对每个 ID 向服务 B 发送一个 HTTP GET 请求(无法更改),然后服务 B 以
的格式响应正确的信息
{
success: true,
user: {
name: 'John Doe'
}
}
无效但我当前使用的代码
incidents.forEach((name) => {
foo = {
nameID: names
}
const asyncForEach = async (array, callback) => {
for(let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
const startMulti = async () => {
await asyncForEach(foo.nameID, async (obj, index) => {
await userController.userInfo(obj)
.then((userInfo) => {
foo.nameID[index] = userInfo.user.name
})
.then(() => {
foobarArray.push(foo)
})
})
return res.json({success: true, foobar: foobarArray})
}
startMulti()
})
从这个博客中获得了嵌套 foreach 循环的原始想法 post 这让我之前可以做另一个,尽管这个不起作用
https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
编辑显示变量
让 foo
让 foobarArray = []
添加等待到用户控制器现在得到正确的输出但错误消息说 Cannot set headers after they are sent to the client
名称来自代码外部,只需要它所在的地方。不知道如何在不解释 whole/detail.
中的项目的情况下解释它
编辑 usercontroller.userinfo
的显示代码
exports.userInfo = function(id) {
return new Promise((resolve, reject) => {
let user = {
_id: id
}
options.json = {user}
request.get('/userInfo', options, (err, response, body) => {
resolve(body)
})
})
}
此代码按预期完美工作 - 即它发送带有正确负载的请求和 returns 正确响应。
编辑当前代码尝试
let foobarArray =[]
let names = []
let foo
for (const incident of incidents) {
foo = {
nameID: names
}
for (const id of incident.names) {
const userInfo = await userController.userInfo(id)
names.push(userInfo.user.name)
}
}
return res.json({success: true, fooreturned: foobarArray})
userController前面await导致的错误信息
SyntaxError: await is only valid in async function
编辑制作异步函数的尝试(我通常不使用 async/await 而是使用 promises)
即使在尝试下面的代码之后它仍然会给出上面的错误消息 - 我在编辑以显示错误消息之前尝试过相同的代码
exports.userInfo = async function(id) {
return new Promise((resolve, reject) => {
let user = {
_id: id
}
options.json = {user}
request.get('/userInfo', options, (err, response, body) => {
resolve(body)
})
})
}
下面的完整代码,上面已经显示的 userInfo 函数除外。
exports.monitor = function(req, res, next) {
const fooID = req.params.id
let foobarArray =[]
let names = []
let foo
Incident.find({fooID})
.exec((err, incidents) => {
if(err) {
console.log(err)
return res.json({success: false, foobar: []})
}
if(incidents != []) {
for (const incident of incidents) {
foo = {
nameID: incident.foo[0].names
}
for (const id of foo.responded) {
const userInfo = await userController.userInfo(id)
names.push(userInfo.user.name)
}
}
return res.json({success: true, foobar: foobarArray})
}
})
}
除了我还需要添加的一些日志记录行之外,这几乎就是全部代码了。我非常需要 foobar: foobarArray
成为一个对象数组 - foo
- 其中 nameID
是专有名称而不是 ID 的数组。通过传递 ID 的 userController.userInfo
获取专有名称。
编辑 - 异步和 promisify 之后的新代码 - 不确定我是否正确执行了 promisify
exports.monitor = async function(req, res, next) {
const fooID = req.params.id
const incidents = await userController.incidentFind(fooID)
}
exports.incidentFind = async function(id) {
return new Promise((resolve, reject) => {
const sevenAgo = moment().subtract(7, 'days').toISOString()
let alertArray =[]
let names = []
let alert
Incident.find({monitorID, createdAt: {$gte: sevenAgo}})
.exec((err, incidents) => {
if(err) {
console.log(err)
return res.json({success: false, foobar: []})
}
if(incidents != []) {
for (const incident of incidents) {
foo = {
nameID: incident.foo[0].names
}
for (const id of foo.responded) {
const userInfo = await userController.userInfo(id)
names.push(userInfo.user.name)
}
}
return res.json({success: true, foobar: foobarArray})
}
})
})
}
不确定实际控制人monitor
应该包含什么内容。有点丢失
错误信息
/home/me/Projects/app/incidents/controllers/users.js:100
const userInfo = await userController.userInfo(id)
^^^^^
SyntaxError: await is only valid in async function
看起来该函数应该已经是异步的(将异步放在 function
名称之前)。
我认为你正在寻找一个简单的
exports.monitor = async function(req, res, next) {
const fooID = req.params.id
const foobarArray = […]
const names = […]
try {
const incidents = await Incident.find({fooID}).exec()
for (const name of incidents) {
const foo = {
nameID: []
}
for (const userId of names) {
const userInfo = await userController.userInfo(userId)
foo.nameID.push(userInfo.user.name)
}
foobarArray.push(foo)
}
res.json({success: true, foobar: foobarArray})
} catch(err) {
console.log(err)
res.json({success: false, foobar: []})
}
}
我正在做一些需要嵌套 foreach 循环来处理一些数据的事情。
目的是我需要查找一个 ID 数组,每个 ID 都与一个用户相关,我只需要从 API 调用的响应中提取他们的名字。服务 A 有 ID 列表,然后针对每个 ID 向服务 B 发送一个 HTTP GET 请求(无法更改),然后服务 B 以
的格式响应正确的信息{
success: true,
user: {
name: 'John Doe'
}
}
无效但我当前使用的代码
incidents.forEach((name) => {
foo = {
nameID: names
}
const asyncForEach = async (array, callback) => {
for(let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}
const startMulti = async () => {
await asyncForEach(foo.nameID, async (obj, index) => {
await userController.userInfo(obj)
.then((userInfo) => {
foo.nameID[index] = userInfo.user.name
})
.then(() => {
foobarArray.push(foo)
})
})
return res.json({success: true, foobar: foobarArray})
}
startMulti()
})
从这个博客中获得了嵌套 foreach 循环的原始想法 post 这让我之前可以做另一个,尽管这个不起作用
https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
编辑显示变量
让 foo 让 foobarArray = []
添加等待到用户控制器现在得到正确的输出但错误消息说 Cannot set headers after they are sent to the client
名称来自代码外部,只需要它所在的地方。不知道如何在不解释 whole/detail.
中的项目的情况下解释它编辑 usercontroller.userinfo
的显示代码exports.userInfo = function(id) {
return new Promise((resolve, reject) => {
let user = {
_id: id
}
options.json = {user}
request.get('/userInfo', options, (err, response, body) => {
resolve(body)
})
})
}
此代码按预期完美工作 - 即它发送带有正确负载的请求和 returns 正确响应。
编辑当前代码尝试
let foobarArray =[]
let names = []
let foo
for (const incident of incidents) {
foo = {
nameID: names
}
for (const id of incident.names) {
const userInfo = await userController.userInfo(id)
names.push(userInfo.user.name)
}
}
return res.json({success: true, fooreturned: foobarArray})
userController前面await导致的错误信息
SyntaxError: await is only valid in async function
编辑制作异步函数的尝试(我通常不使用 async/await 而是使用 promises)
即使在尝试下面的代码之后它仍然会给出上面的错误消息 - 我在编辑以显示错误消息之前尝试过相同的代码
exports.userInfo = async function(id) {
return new Promise((resolve, reject) => {
let user = {
_id: id
}
options.json = {user}
request.get('/userInfo', options, (err, response, body) => {
resolve(body)
})
})
}
下面的完整代码,上面已经显示的 userInfo 函数除外。
exports.monitor = function(req, res, next) {
const fooID = req.params.id
let foobarArray =[]
let names = []
let foo
Incident.find({fooID})
.exec((err, incidents) => {
if(err) {
console.log(err)
return res.json({success: false, foobar: []})
}
if(incidents != []) {
for (const incident of incidents) {
foo = {
nameID: incident.foo[0].names
}
for (const id of foo.responded) {
const userInfo = await userController.userInfo(id)
names.push(userInfo.user.name)
}
}
return res.json({success: true, foobar: foobarArray})
}
})
}
除了我还需要添加的一些日志记录行之外,这几乎就是全部代码了。我非常需要 foobar: foobarArray
成为一个对象数组 - foo
- 其中 nameID
是专有名称而不是 ID 的数组。通过传递 ID 的 userController.userInfo
获取专有名称。
编辑 - 异步和 promisify 之后的新代码 - 不确定我是否正确执行了 promisify
exports.monitor = async function(req, res, next) {
const fooID = req.params.id
const incidents = await userController.incidentFind(fooID)
}
exports.incidentFind = async function(id) {
return new Promise((resolve, reject) => {
const sevenAgo = moment().subtract(7, 'days').toISOString()
let alertArray =[]
let names = []
let alert
Incident.find({monitorID, createdAt: {$gte: sevenAgo}})
.exec((err, incidents) => {
if(err) {
console.log(err)
return res.json({success: false, foobar: []})
}
if(incidents != []) {
for (const incident of incidents) {
foo = {
nameID: incident.foo[0].names
}
for (const id of foo.responded) {
const userInfo = await userController.userInfo(id)
names.push(userInfo.user.name)
}
}
return res.json({success: true, foobar: foobarArray})
}
})
})
}
不确定实际控制人monitor
应该包含什么内容。有点丢失
错误信息
/home/me/Projects/app/incidents/controllers/users.js:100
const userInfo = await userController.userInfo(id)
^^^^^
SyntaxError: await is only valid in async function
看起来该函数应该已经是异步的(将异步放在 function
名称之前)。
我认为你正在寻找一个简单的
exports.monitor = async function(req, res, next) {
const fooID = req.params.id
const foobarArray = […]
const names = […]
try {
const incidents = await Incident.find({fooID}).exec()
for (const name of incidents) {
const foo = {
nameID: []
}
for (const userId of names) {
const userInfo = await userController.userInfo(userId)
foo.nameID.push(userInfo.user.name)
}
foobarArray.push(foo)
}
res.json({success: true, foobar: foobarArray})
} catch(err) {
console.log(err)
res.json({success: false, foobar: []})
}
}