等待forEach循环结束以呈现-Javascript
我在读关于如何解决这个问题的书,每个人都说我应该使用“异步”和“等待”,但我不知道如何在我的代码中恰当地使用它。(我正在制作一个新的JSON,我应该将它发送到前端,但我需要先等待JSON在forEach循环中准备好,然后在屏幕上渲染) 我试过很多种方法,但没有一种效果好。等待forEach循环结束以呈现-Javascript,javascript,node.js,Javascript,Node.js,我在读关于如何解决这个问题的书,每个人都说我应该使用“异步”和“等待”,但我不知道如何在我的代码中恰当地使用它。(我正在制作一个新的JSON,我应该将它发送到前端,但我需要先等待JSON在forEach循环中准备好,然后在屏幕上渲染) 我试过很多种方法,但没有一种效果好。 如果我犯了一些错误,很抱歉。在调用res.render()之前,您没有正确地等待完成所有异步操作,因此在尝试使用数组时,数组是空的或部分填充。因此,您需要使用承诺来跟踪何时一切都完成了 你有两个选择。您可以并行或按顺序运行所有
如果我犯了一些错误,很抱歉。在调用
res.render()
之前,您没有正确地等待完成所有异步操作,因此在尝试使用数组时,数组是空的或部分填充。因此,您需要使用承诺来跟踪何时一切都完成了
你有两个选择。您可以并行或按顺序运行所有请求。我将展示这两个方面的示例:
下面是并行处理所有数据库请求。这将链接各种承诺,并使用Promise.all()
了解它们何时完成。控件中的结果\u cadastrados
没有任何特定顺序,但这可能比按顺序处理所有内容运行得更快
router.get('/', (req, res) => {
Controle.find()
.lean()
.then(controles => {
const controles_cadastrados = [];
Promise.all(controles.map(controle => {
return Sensor.find({ id_mac: controle.sensor })
.lean()
.then(sensor => {
controle.sensor_nome = sensor[0].nome;
return Atuador.find({ id_mac: controle.atuador })
.lean()
.then(atuador => {
controle.atuador_nome = atuador[0].nome;
controles_cadastrados.push(controle);
console.log(controles_cadastrados);
});
});
})).then(() => {
//wait to send the response
res.render('controle/controles', {
controles: controles_cadastrados,
});
});
}).catch(erro => {
console.log('Erro ao carregar controles');
res.sendStatus(500);
});
});
下面是如何使用async/await
对操作进行排序:
router.get('/', async (req, res) => {
try {
let controles = await Controle.find().lean();
const controles_cadastrados = [];
for (let controle of controles) {
let sensor = await Sensor.find({ id_mac: controle.sensor }).lean();
controle.sensor_nome = sensor[0].nome;
let atuador = await Atuador.find({ id_mac: controle.atuador }).lean()
controle.atuador_nome = atuador[0].nome;
controles_cadastrados.push(controle);
console.log(controles_cadastrados);
}
//wait to send the response
res.render('controle/controles', {
controles: controles_cadastrados,
});
} catch(e) {
console.log(e, 'Erro ao carregar controles');
res.sendStatus(500);
}
});
另外,请注意,此处捕获所有可能被拒绝的承诺或其他错误,并且始终向传入的http请求发送响应,即使出现错误。在调用
res.render()之前,您没有正确地等待完成所有异步操作
因此,当您尝试使用阵列时,阵列为空或部分填充。因此,您需要使用承诺来跟踪何时一切都完成了
你有两个选择。您可以并行或按顺序运行所有请求。我将展示这两个方面的示例:
下面是并行处理所有数据库请求。这将链接各种承诺,并使用Promise.all()
了解它们何时完成。控件中的结果\u cadastrados
没有任何特定顺序,但这可能比按顺序处理所有内容运行得更快
router.get('/', (req, res) => {
Controle.find()
.lean()
.then(controles => {
const controles_cadastrados = [];
Promise.all(controles.map(controle => {
return Sensor.find({ id_mac: controle.sensor })
.lean()
.then(sensor => {
controle.sensor_nome = sensor[0].nome;
return Atuador.find({ id_mac: controle.atuador })
.lean()
.then(atuador => {
controle.atuador_nome = atuador[0].nome;
controles_cadastrados.push(controle);
console.log(controles_cadastrados);
});
});
})).then(() => {
//wait to send the response
res.render('controle/controles', {
controles: controles_cadastrados,
});
});
}).catch(erro => {
console.log('Erro ao carregar controles');
res.sendStatus(500);
});
});
下面是如何使用async/await
对操作进行排序:
router.get('/', async (req, res) => {
try {
let controles = await Controle.find().lean();
const controles_cadastrados = [];
for (let controle of controles) {
let sensor = await Sensor.find({ id_mac: controle.sensor }).lean();
controle.sensor_nome = sensor[0].nome;
let atuador = await Atuador.find({ id_mac: controle.atuador }).lean()
controle.atuador_nome = atuador[0].nome;
controles_cadastrados.push(controle);
console.log(controles_cadastrados);
}
//wait to send the response
res.render('controle/controles', {
controles: controles_cadastrados,
});
} catch(e) {
console.log(e, 'Erro ao carregar controles');
res.sendStatus(500);
}
});
此外,请注意,所有可能被拒绝的承诺或其他错误都会在此处捕获,并且始终会向传入的http请求发送响应,即使出现错误。谢谢!很好的解释,很有魅力。致以最良好的祝愿。@Donada-如果这回答了您的问题,那么您可以通过单击答案左侧的复选标记向社区表明这一点。这也会为你赢得一些声誉点,因为你遵循了正确的程序。谢谢!很好的解释,很有魅力。致以最良好的祝愿。@Donada-如果这回答了您的问题,那么您可以通过单击答案左侧的复选标记向社区表明这一点。这也将为你赢得一些声誉点在这里遵循正确的程序。