Я знаю, что это обычная проблема для людей, и я посмотрел некоторые руководства и посмотрел на документы, но я не понимаю, что происходит, и хотел бы помочь.
Здесьэто функция контроллера, над которой я работаю:
exports.appDetail = function (req, res) {
appRepo.findWithId(req.params.id, (err, myApp) => {
if (err) {
console.log(err)
}
getDeviceData(myApp.devices, (err, myDeviceData) => {
if (err) console.log(err)
console.log(JSON.stringify(myDeviceData) + ' || myDeviceData')
// construct object to be returned
let appsDataObject = {
name: myApp.name,
user_id: myApp.user_id,
devices: myDeviceData,
permissions: myApp.permissions
}
return res.status(200).send(appsDataObject)
})
})
}
// write async function here
const getDeviceData = function (devices, callback) {
let devicesDataArray = []
async.each(devices, function (device, cb) {
deviceRepo.findById(new ObjectID(device), (err, myDevice) => {
if (err) {
cb(err)
}
// get device data, push to devices array
let deviceObj = {
name: myDevice.name,
version: myDevice.version
}
devicesDataArray.push(deviceObj)
console.log(JSON.stringify(devicesDataArray) + ' || devicesDataAray after obj push')
})
cb(null, devicesDataArray)
}, function (err) {
// if any of the file processing produced an error, err would equal that error
if (err) console.log(err)
})
callback(null, devicesDataArray)
}
Первоначально я написал это с помощью цикла for и обратного вызова, но я думаю, что это было невозможно сделать (хотя я не уверен в этом),Если есть лучший способ сделать асинхронный цикл, пожалуйста, дайте мне знать.
В ~ строке 8 есть оператор журнала myDeviceData
. Это должно возвращать данные, которые я хочу, через обратный вызов, но этот оператор журнала всегда возвращается пустым. А поскольку другие операторы журнала показывают, что данные форматируются правильно, проблема должна заключаться в возврате нужных мне данных через обратный вызов getDeviceData()
. Предположительно, callback(null, devicesDataArray)
должен сделать это.
Я не понимаю, как эти асинхронные функции должны работать, ясно. Может кто-нибудь помочь мне понять, как я должен получить значения из этих функций async.each? Спасибо.
РЕДАКТИРОВАТЬ: я переработал код, чтобы попытаться сделать его более понятным и лучше подходить к проблеме, и я точно определил, где проблема. В начале функции this я определяю devicesDataArray
как пустой массив, а в конце возвращаю массив. Все внутри происходит так, как должно, но я не знаю, как заставить возврат ждать, пока массив не станет пустым, если это имеет смысл, вот новый код:
let getData = async function (devices) {
let devicesDataArray = []
for (let i = 0; i < devices.length; i++) {
deviceRepo.findById(new ObjectID(devices[i]), async (err, myDevice) => {
if (err) {
console.log(err)
}
console.log(JSON.stringify(myDevice) + ' || myDevice')
let deviceObj = await {
name: myDevice.name,
version: myDevice.version
}
console.log(JSON.stringify(deviceObj) + ' || deviceObj')
await devicesDataArray.push(deviceObj)
console.log(JSON.stringify(devicesDataArray) + ' || devicesDataArray after push')
})
}
console.log(JSON.stringify(devicesDataArray) + ' || devicesDataArray before return')
return Promise.all(devicesDataArray) // problem is here.
}
Любая помощьк пониманию это ценится.