【发布时间】:2020-09-12 05:23:04
【问题描述】:
我正在做一些需要嵌套 foreach 循环来处理一些数据的事情。
我需要查找一组 ID,每个 ID 都与一个用户相关,我只需要从 API 调用的响应中提取他们的名称。服务 A 拥有 ID 列表,然后针对每个 ID 向服务 B 发送 HTTP GET 请求(无法更改),然后以
格式的正确信息进行响应{
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 循环的原始想法,这让我之前可以做另一个,尽管这个不起作用
https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
编辑显示变量
让 foo 让 foobarArray = []
向用户控制器添加了等待,现在可以得到正确的输出,但错误消息显示Cannot set headers after they are sent to the client
名称来自代码外部,并且只需要它所在的位置。在不完整/详细解释项目的情况下不知道如何解释。
编辑 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)
})
})
}
此代码按预期完美运行 - 即它使用正确的负载发送请求并返回正确的响应。
编辑当前代码尝试
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 而是使用 Promise)
即使在下面的尝试代码之后,它仍然会给出上面的错误消息 - 我在编辑以显示错误消息之前尝试了相同的代码
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 获取专有名称。
edit - async 和 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 名称之前)。
【问题讨论】:
-
您永远不会等待来自
userController.userInfo()的承诺。此外,您的代码中有多个未声明的变量,您不能多次发送响应。 -
@Bergi 没有未声明的变量,它们是在代码显示之外声明的。我知道它多次发送响应,但是我不知道如何让它只发送一次而不跳过其他代码 - 这是一个问题
-
请发布完整示例所需的全部代码。否则我们无法判断实际问题是什么,到目前为止我还没有回答,因为我不知道如何在适当的解决方案中对待
foobarArray。 -
@Bergi 在上面的代码之外有两个变量,foo。至于 foobarArray,它从一个空数组开始,在上述代码的第 16 行,它显示了一个推入
foo的数组。然后是 foo ,它只在 foo 附近添加 nameID 的顶部附近被引用。这就是这段代码中显示的所有变量。如果我将 await 添加到 userController 部分,它会给我正确的输出,但它也会在节点控制台中给我一条错误消息,说Cannot set headers after they are sent to the client我预期但不确定如何解决 -
你可以在edit 你的问题中包含这些:-) 另外,
names是什么?
标签: javascript node.js foreach nested-loops