【问题标题】:Force route in express强制使用快递路线
【发布时间】:2018-03-17 19:21:44
【问题描述】:

可以强制路由吗?

示例:

我有这条路线A

notiSchema = 通知模型

router.get('/set', function(req, res){
    User.findById("userId". function(err, foundUser){
        foundUser.notiSchemaSent.forEach(function(notiSchema, i){
            if(req.user.notifications.length === 0){
                req.user.notifications.unshift(notiSchema);
                req.user.save();
            } else {
                req.user.notifications.forEach(function(userSchema, i){
                    if(req.user.notifications.indexOf(notiSchema) === -1){
                         req.user.notifications.unshift(notiSchema);
                         req.user.save();
                    }
                });
            }
        });
    });

    res.json(req.user.notifications);
});

这里的问题是在 userB 更新之前读取了“res.json”行

所以我创建了这条其他路线B

router.get('/get', middleware.isLoggedIn, function(req, res){
  res.json(req.user.notifications);
});

我的Ajax

$.get('/set', function(data){
    // I only add a "fa-spin" class here
}).then(function(){
    $.get('/get', function(data){
        $(data).each(function(i, item){
            $('.notDrop').prepend(item);
        });

        // Remove the "fa-spin" class
    });
}); 

但有时路由“B”在“A”结束之前被调用;

所以我想知道是否只有在“A”完全完成后才可以调用“B”路线。

【问题讨论】:

  • 你不需要强制路由,这个概念也没有多大意义。您只需要适当地编写您的路线,这样您就不会在异步操作完成之前发送响应。您的 .save() 操作应该有一个回调或承诺,告诉您何时完成,并且仅在完成后发送您的响应。此外,您可能需要停止使用.forEach(),这样您就可以在找到您要查找的那个时停止循环,然后在.save() 完成后发送响应。
  • 为了更具体地帮助您,我们必须查看真实代码,而不是伪代码,因为不清楚您在嵌套的 .forEach() 循环中真正想要做什么以及为了向您展示如何为循环中的异步操作正确编码,需要您真正尝试做的事情。在 stackoverflow 上,我们对真实代码的实际解决方案比对伪代码的假设解决方案更有帮助。
  • @jfriend00 嘿,我开始使用 forEach 是因为我读到它可以帮助解决异步问题。发布更新

标签: javascript ajax mongodb express asynchronous


【解决方案1】:

我重写了您的路线以将所有更改累积到 req.user.notifications 中,然后在最后保存一次(如果修改了数组)。这样您就可以只进行一次.save() 操作,并通过向其传递回调来知道它何时完成。

变更摘要:

  1. 在数组中累加结果,只在最后保存。
  2. 仅在数组被修改时保存。
  3. 去掉 .length === 0 的特殊情况,因为这不是必需的。
  4. 使用req.user.save() 上的回调来知道它什么时候完成,这样我们就可以了。保存完成后发送响应。
  5. .save() 添加错误处理。
  6. .findById() 添加错误处理

代码如下:

router.get('/set', function(req, res){
    User.findById("userId", function(err, foundUser){
        if (err) {
           console.log(err);
           res.status(500).send("Error finding user.")
           return;
        }
        let origLength = req.user.notifications.length;
        foundUser.notiSchemaSent.forEach(function(notiSchema, i){
            req.user.notifications.forEach(function(userSchema, i){
                if(req.user.notifications.indexOf(notiSchema) === -1){
                    req.user.notifications.unshift(notiSchema);
                }
            });
        });
        if (req.user.notifications.length !== origLength) {
            req.user.save(function(err) {
                if (err) {
                    console.log(err);
                    res.status(500).send("Error saving user notifications.")
                } else {
                    res.json(req.user.notifications);
                }
            });
        } else {
            res.json(req.user.notifications);
        }
    });
});

如果您更改数据库代码以便从查找操作中获取一组用户,那么您可以像这样处理这些:

router.get('/set', function(req, res){
    User.find({_id: {$in: arrayOfIds}}, function(err, foundUsers){
        if (err) {
           console.log(err);
           res.status(500).send("Error finding user.")
           return;
        }
        let origLength = req.user.notifications.length;
        foundUsers.forEach(function(foundUser) {
            foundUser.notiSchemaSent.forEach(function(notiSchema, i){
                req.user.notifications.forEach(function(userSchema, i){
                    if(req.user.notifications.indexOf(notiSchema) === -1){
                        req.user.notifications.unshift(notiSchema);
                    }
                });
            });
        });
        if (req.user.notifications.length !== origLength) {
            req.user.save(function(err) {
                if (err) {
                    console.log(err);
                    res.status(500).send("Error saving user notifications.")
                } else {
                    res.json(req.user.notifications);
                }
            });
        } else {
            res.json(req.user.notifications);
        }
    });
});

【讨论】:

  • 显示此错误 Can't set headers after they are sent (但只有一次)
  • 现在它没有显示任何错误,但它没有向用户数据库添加任何内容
  • @BrunoPigatto - 您是否进行了任何调试以查看代码遵循的路径并查看实际发生的情况。我没有能力运行它,所以如果某些东西不起作用,你就是必须进行调试的人。 “没用”并没有告诉我们任何有用的信息让我们可以帮助您。
  • 嘿,问题是我正在使用具有 0 个通知的用户进行测试,因此“req.user.notifications.forEach”行不起作用,现在我修复了它。谢谢!
  • @BrunoPigatto - 我添加了一个包含用户数组的示例。
猜你喜欢
  • 1970-01-01
  • 2019-03-11
  • 2016-07-03
  • 1970-01-01
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多