Nodejs 异步的问题 用数组保存json数据 死活都保存不进去
Nodejs 异步的问题 用数组保存json数据 死活都保存不进去
app.get(’/homepage/:user’,function(req,res){
var lessoninfoarray = {};
var classarray = [];
User.find({username:req.params.user},function(err,doc){
if(doc.length!=0){
UC.find({ userid:doc[0].id },function(err,docs){
if(docs.length!=0){
for(var j=0;j<docs.length;j++){
Class.findById(docs[j].classid,function(err,classinfo){
classarray.push(classinfo);
});
}
console.log(“classarray is :”+classarray); // 这里是空
res.render(‘homepage’,{title:‘homepage’,classinfodoc:JSON.stringify(classarray)});
}else{
res.render(‘homepage’,{title:‘homepage’,classinfodoc:[]});
}
});
}else{
res.redirect('/register');
}
});
});
Node.js 异步的问题:用数组保存 JSON 数据时无法成功保存
在使用 Node.js 处理异步操作时,经常会遇到数组无法按预期填充数据的情况。这通常是由于对异步操作的误解导致的。在你的例子中,Class.findById
是一个异步操作,而你试图在所有异步操作完成之前就访问 classarray
数组。
示例代码及解释
为了确保所有的异步操作都完成后再处理 classarray
,我们可以使用 Promise.all
来等待所有的异步操作完成。
const express = require('express');
const User = require('./models/User'); // 假设这是用户模型
const UC = require('./models/UC'); // 假设这是关联模型
const Class = require('./models/Class'); // 假设这是班级模型
const app = express();
app.get('/homepage/:user', function(req, res) {
User.findOne({ username: req.params.user })
.then(doc => {
if (!doc) {
return res.redirect('/register');
}
return UC.find({ userid: doc.id });
})
.then(docs => {
if (docs.length === 0) {
return res.render('homepage', { title: 'homepage', classinfodoc: [] });
}
const promises = docs.map(doc =>
Class.findById(doc.classid).exec()
);
return Promise.all(promises);
})
.then(classarray => {
console.log("classarray is :" + classarray);
res.render('homepage', { title: 'homepage', classinfodoc: JSON.stringify(classarray) });
})
.catch(err => {
console.error(err);
res.status(500).send('Server error');
});
});
module.exports = app;
解释
User.findOne
: 查找用户信息。UC.find
: 根据用户 ID 查找关联信息。Promise.all
: 确保所有的Class.findById
操作都完成后才继续执行。res.render
: 渲染页面并将数据传递给前端。
通过这种方式,我们确保了所有的异步操作都在渲染页面之前完成,从而避免了数组未填充完整的问题。
for(var j=0;j<docs.length;j++){
Class.findById(docs[j].classid,function(err,classinfo){
classarray.push(classinfo);
});
}
console.log("classarray is :"+classarray); // 这里是空
哥,push是回调里执行的,这里要用async,enventproxy之类的流程控制才方便,不要受同步编程的影响
大兄弟啊 !!给个例子吧 我被折磨疯了
没例子就不明白就先了解了解javascript的异步到底是啥意思吧。要不你要例子会要疯的。
你过个5秒,在console里查看一下classarray的内容。 你现在的console.log早了点。
你的问题出在异步操作上。Class.findById
是一个异步操作,当你调用 console.log("classarray is :" + classarray);
和 res.render
时,Class.findById
的回调函数可能还没有执行完毕,因此 classarray
仍然是空的。
为了解决这个问题,你可以使用 async/await
或者 Promise.all
来确保所有的异步操作完成后再进行后续处理。这里提供一个使用 async/await
的示例代码:
const async = require('async');
app.get('/homepage/:user', async function (req, res) {
try {
const user = await User.findOne({ username: req.params.user });
if (!user) {
return res.redirect('/register');
}
const ucDocuments = await UC.find({ userid: user.id });
if (ucDocuments.length === 0) {
return res.render('homepage', { title: 'homepage', classinfodoc: [] });
}
const classPromises = ucDocuments.map(uc => Class.findById(uc.classid));
const classInfos = await Promise.all(classPromises);
console.log("classarray is :" + JSON.stringify(classInfos)); // 现在应该不是空
res.render('homepage', { title: 'homepage', classinfodoc: JSON.stringify(classInfos) });
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});
在这个例子中,我们使用了 async/await
和 Promise.all
来确保所有异步操作完成后才继续执行后续逻辑。这样可以保证 classarray
在渲染页面之前已经被正确填充。