Я работаю над чем-то, что требует вложенных циклов foreach для обработки некоторых данных.
Имеется в виду массив идентификаторов, которые мне нужно найти, каждый идентификатор, связанный с пользователем, и мне просто нужно извлечь их имена из ответа на вызов API. Служба A имеет список идентификаторов и затем отправляет 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 из этого сообщения в блоге, что позволило мне сделать еще один раньше, хотя этот не будет работать
https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
редактировать переменные показа
let foo let 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)
})
})
}
Этот код работает отлично, как ожидалось - ie он отправляет запрос с правильной полезной нагрузкой и возвращает правильный ответ.
Попытка редактирования текущего кода
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
SyntaxError: await is only valid in async function
попытка редактирования при выполнении функции asyn c (обычно я не 'не используйте async / await вместо использования обещаний)
Даже после кода попытки ниже он все еще дает сообщение об ошибке выше - я пробовал тот же код, прежде чем редактировать, чтобы показать сообщение об ошибке
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
- это массив имен собственных, а не идентификаторов. Собственные имена выбираются через userController.userInfo
, куда передается идентификатор.
edit - Новый код после asyn c и 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
Похоже, функция должна быть асинхронной c уже (поместите asyn c перед function
name).