Javascript 同步foreach和render 2查询结果节点

Javascript 同步foreach和render 2查询结果节点,javascript,node.js,foreach,promise,async-await,Javascript,Node.js,Foreach,Promise,Async Await,我刚开始使用NodeJS,这个问题已经困扰了我两天多了! 如果有人能帮助我,我将非常感激 我正在尝试获取一个查询结果,然后映射所有结果并应用另一个查询,然后呈现两个查询结果。这是我的密码: app.get('/home/', function(req, res) { let sessionUser = req.session.user; if(sessionUser) { user.findMemosByUserId(sessionUser.id, function(result) {

我刚开始使用NodeJS,这个问题已经困扰了我两天多了! 如果有人能帮助我,我将非常感激

我正在尝试获取一个查询结果,然后映射所有结果并应用另一个查询,然后呈现两个查询结果。这是我的密码:

app.get('/home/', function(req, res) { 
let sessionUser = req.session.user;
if(sessionUser) {
    user.findMemosByUserId(sessionUser.id, function(result) {
        result.forEach(function(memo){
            //get users having acces to each memo
            user.findUsersByMemoId(memo.id, function(result2){
                var obj = {};
                obj[memo.id] = [];
                result2.forEach(function(res){
                    obj[memo.id].push(res.username);
                });
                req.session.sharings.push(obj);
                console.log(req.session.sharings); //it shows this
            });
        });
        console.log(req.session.sharings); //it shows this first
        res.render('home.ejs', {memos: result, sharingsData: req.session.sharings});
    });

    return;
}
res.redirect('/');})
然后问题是它在循环和获取每个备忘录用户之前呈现页面(而req.session.sharings仍然为空)

登录结果为:

[ ]    
[{ },{ }] // with my data 
任何人都知道我如何强制:

 res.render('home.ejs', {memos: result, sharingsData: req.session.sharings});   

等待每个循环结束

首先,如果要从回调函数返回值,我建议在
Array.prototype.forEach
上使用
Array.prototype.map
。其次,您可以创建自己的
Promise
,它将在函数调用完成时解决请求会话的问题。我不确定您是否真的需要手动编写Sharing,因此我决定将它们分组,并仅在收集完之后才将它们推到
session.sharings
数组中

app.get('/home/', (req, res) => {
    let sessionUser = req.session.user;
    if (!sessionUser) return res.redirect('/');

    user.findMemosByUserId(sessionUser.id, result => {
        Promise.all(result.map(memo => {
            return new Promise(resolve => {
                user.findUsersByMemoId(memo.id, result2 => {
                    const obj = {[memo.id]: result2.map(res => res.username)};
                    resolve(obj)
                });
            });
        })).then(sharings => {
            req.session.sharings.push(...sharings);
            console.log(req.session.sharings);
            res.render('home.ejs', {memos: result, sharingsData: req.session.sharings});
        });
    });
});

首先,如果希望从回调函数返回值,我建议在
Array.prototype.forEach
上使用
Array.prototype.map
。其次,您可以创建自己的
Promise
,它将在函数调用完成时解决请求会话的问题。我不确定您是否真的需要手动编写Sharing,因此我决定将它们分组,并仅在收集完之后才将它们推到
session.sharings
数组中

app.get('/home/', (req, res) => {
    let sessionUser = req.session.user;
    if (!sessionUser) return res.redirect('/');

    user.findMemosByUserId(sessionUser.id, result => {
        Promise.all(result.map(memo => {
            return new Promise(resolve => {
                user.findUsersByMemoId(memo.id, result2 => {
                    const obj = {[memo.id]: result2.map(res => res.username)};
                    resolve(obj)
                });
            });
        })).then(sharings => {
            req.session.sharings.push(...sharings);
            console.log(req.session.sharings);
            res.render('home.ejs', {memos: result, sharingsData: req.session.sharings});
        });
    });
});

这回答了你的问题吗?另一个问题很好地概括了这个问题。有一点不同,您不需要返回一个值,但它在逻辑上是等价的——您希望在异步操作完成后生成一条语句。您可以
等待
或使用Promise API或将
res.render
作为
之后的回调中的最后一个调用。这些将确保在完成操作后进行渲染。异步性、其影响以及如何处理也与此相关:如果您不使用它们,为什么要将其标记为
async
/
wait
?这是否回答了您的问题?另一个问题很好地概括了这个问题。有一点不同,您不需要返回一个值,但它在逻辑上是等价的——您希望在异步操作完成后生成一条语句。您可以
等待
或使用Promise API或将
res.render
作为
之后的回调中的最后一个调用。这些将确保在完成操作后进行渲染。同样与异步性、其影响以及如何处理相关:如果不使用它们,为什么要将其标记为
async
/
wait