javascript - 如何从异步每个函数返回值?
问题描述
我知道这对人们来说是一个常见问题,我查阅了一些指南并查看了文档,但我不明白发生了什么,希望得到一些帮助。
这是我正在处理的控制器功能:
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 函数中获取值吗?谢谢你。
编辑:我重构了代码以尝试使其更清晰并更好地解决问题,并且我已经确定了问题所在。一开始我将这个函数定义devicesDataArray
为一个空数组,最后我返回这个数组。里面的一切都按原样发生,但我不知道如何告诉 return 等到数组不为空,如果这有意义的话,这是新代码:
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.
}
感谢您对理解这一点的任何帮助。
解决方案
这里我们使用Promise
该Promise
对象立即返回,我们在那里执行我们的异步代码。
const someFuncThatTakesTime = () => {
// Here is our ASYNC
return new Promise((resolve, reject) => {
// In here we are synchronous again.
const myArray = [];
for(x = 0; x < 10; x++) {
myArray.push(x);
}
// Here is the callback
setTimeout(() => resolve(myArray), 3000);
});
};
someFuncThatTakesTime().then(array => console.log(array));
推荐阅读
- python-3.x - 熊猫框架和列表之间的有效元素比较
- sql - 如何为某些字段值选择唯一的
- migration - PHP Magento 电子商务商店迁移到其他 CMS
- switch-statement - 将 if 语句嵌套在 switch 语句中是不好的做法吗?
- pine-script - 交易视图不能在“if”或“for”中调用“security”或“financial”
- firebase - 有条件的图像
- java - how pattern syntax exception works
- excel - 切片器的迭代在 Excel VBA 中不起作用
- powershell - Jenkins、Powershell 插件和 Windows 安全更新 KB5004285
- javascript - PDF 表单:使文本字段在打印时可见