#node.js #reactjs #mongodb #express
#node.js #reactjs #mongodb #выразить
Вопрос:
У меня проблема с асинхронной функцией и обратными вызовами в узле js. Мне нужно получить все сообщения моих друзей и отобразить их. Но если я сделаю это без setTimeout(), это вернет только некоторую часть данных. Как я могу решить эту проблему, не устанавливая setTimeout? Конечно, абсурдно ждать 5-6 или 10 секунд, чтобы получить все данные. Я также пробовал с Promises, но снова ответ неполный. Пожалуйста, кто-нибудь может мне помочь?
//Sending request with axios to Controller
axios.post(packages.proxy 'users/getFriendsPosts',{id: user_id},config)
.then(res => {
// Code for displaying result
})
//User Controller
router.post("/getFriendsPosts", getFriendsPosts);
//Send request body to userService.js
function getFriendsPosts(req, res, next) {
userService.getFriendsPosts(req.body, function(posts, user){
res.json({posts,user});
})
.catch(err => next(err));
}
//userService.js
module.exports = {
getFriendsPosts,
};
async function getFriendsPosts(user,callback){
var arr = [];
var array = [];
MongoClient.connect(url, async function(errr, db) {
if (errr) throw errr;
var dbo = db.db("drone-x");
//Find user
dbo.collection("users").find({_id: ObjectId(user.id)}).toArray(async function(err, result) {
if (err) throw err;
result.forEach(async function(element, index) {
if(element.friends.length != 0){
element.friends.forEach(async function(elem) {
//Find user's friends
dbo.collection("users").find({_id: ObjectId(elem.id)}).toArray(async function(error, res) {
if (error) throw error;
//push user's friends to arr
arr.push(res);
res.forEach(async function(elements) {
//Find user's friends posts
dbo.collection("posts").find({userId: elements._id.toString()}).toArray(async function(errors, results) {
if (errors) throw errors;
//push user's friends posts to array
array.push(results);
//callback results through setTimeout
setTimeout(async function(){ await callback(array, arr); db.close(); }, 2000);
});
});
});
});
}
else
{
await callback("0");
}
});
});
});
}
Если я не использую функцию setTimeout, она просто возвращает 2-3 данных, но с помощью setTimeout она возвращает все данные. И если данные будут повышены, то мне нужно увеличить время ожидания. Но, конечно, это плохая идея. Кто-нибудь может мне помочь?
Комментарии:
1. Обещаю решить вашу проблему, но этот массивный запрос занимает слишком много времени. Используйте mongoose или aggregation, чтобы сэкономить немного времени и скорости.
2. @AshokPatidar Я пробовал с Promise, но он снова вернул неполные данные
Ответ №1:
Вы должны использовать try catch в этом коде
getFriendsPosts = async (user,callback) => {
const arr = [];
const array = [];
const db = await MongoClient.connect(url);
const dbo = db.db("drone-x");
const results = await dbo.collection("users").find({_id: ObjectId(user.id)})
const resultPromise = _.map(results, async element => {
const friends = _.get(element, 'friends', [])
if(friends.length != 0) {
const friendPromise = _.map(friends, async friend => {
const ress = await dbo.collection("users").find({_id: ObjectId(friend.id)})
arr.push(ress);
const resPromise = _.map(ress, async res => {
const posts = await dbo.collection("posts").find({userId: res._id.toString()})
const postPromise = _.map(posts, post => {
array.push(post);
})
await Promise.all(postPromise)
})
await Promise.all(resPromise)
})
await Promise.all(friendPromise)
}
})
await Promise.all(resultPromise)
return { arr , array }
}
Я не рекомендую этот способ, это займет слишком много времени. Вы должны использовать mongoose и использовать агрегацию для длинного запроса.
Комментарии:
1. Спасибо, но он снова возвращает неполные данные : (
2. Можете ли вы мне помочь, как я могу это сделать с помощью агрегатов?
3. Это очень длинный запрос, я не знаю, как это сделать с помощью mongoose или aggregates. Пожалуйста, вы можете мне помочь?
4. Проклятие. Можете ли вы поделиться со мной образцом данных для того, чего вы хотите достичь. на mongoplayground. net с помощью bason multi collection я сделаю запрос для вас.
5. Большое вам спасибо. Мне нужно отправить всем моим друзьям все сообщения. Я отправляю идентификатор пользователя с помощью axios. Сначала мне нужно найти пользователя из MongoDB с этим идентификатором. Во-вторых, мне нужно получить друзей этих пользователей, затем мне нужно получить все сообщения друзей пользователей. Затем обратный вызов после получения всех данных. Спасибо! Вот коллекция пользователей mongoplayground.net/p/I7JOLWngZDa И вот коллекция Post mongoplayground.net/p/VqaH8kph98g