【问题标题】:Populate before adding: RangeError: Maximum call stack size exceeded添加前填充: RangeError:超出最大调用堆栈大小
【发布时间】:2017-07-19 22:28:51
【问题描述】:

我想实现一个像 plunker 这样的在线编辑器。我已经定义了以下数据结构:一个post(即一个项目)包含一个folders的列表(表示帖子的不同版本),一个folder只是一个files的列表。

var PostSchema = new mongoose.Schema({
  folders: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Folder' }]
  ...
});

var FolderSchema = new mongoose.Schema({
    files: [{ name: String, body: String, editorOption: Object }],
    post: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
})

我想使用以下请求添加文件夹/版本(通过编辑器上的save 按钮)。注意,因为一个帖子可以同时在不同的地方打开,我们必须在添加版本之前从数据库中获取帖子,然后我们返回最新的帖子到控制器。

o.addFolder = function (id, folder) {
    return $http.post('/posts/' + id + '/editor/folders', folder, {
        headers: { Authorization: 'Bearer ' + auth.getToken() }
    })
}

router.post('/posts/:post/editor/folders', auth, function (req, res, next) {
    req.post.populate('folders', function (err, post) {
        if (err) return next(err);
        var folder = new Folder(req.body);
        folder.post = post;
        folder.save(function (err, folder) {
            if (err) return next(err);
            console.log("3 folder: "); console.log(folder);
            console.log("4 post: "); console.log(post);
            post.folders.push(folder);
            console.log("5 folder: "); console.log(folder);
            console.log("6 post: "); console.log(post);
            post.save(function (err, post) {
                if (err) return next(err);
                res.json({ folder: folder, post: post })
            })
        })
    })
});

这是一个测试日志,它试图将一个包含 2 个文件的文件夹添加到一个空帖子中:

3 folder: 
{ __v: 0,
  post: 
   { _id: 58b5e86d8e328f58f3e87ac2,
     __v: 0,
     folders: [] },
  _id: 58b5e86d8e328f58f3e87ac3,
  files: 
   [ { name: 'index.html',
       body: '<!DOCTYPE html>\n<body>\nindex.html\n</body>\n</html>',
       editorOption: [Object],
       _id: 58b5e86d8e328f58f3e87ac5 },
     { name: 'script.js',
       body: '',
       editorOption: [Object],
       _id: 58b5e86d8e328f58f3e87ac4 } ] }
4 post: 
{ _id: 58b5e86d8e328f58f3e87ac2,
  __v: 0,
  folders: [] }
5 folder: 
events.js:85
      throw er; // Unhandled 'error' event
            ^
RangeError: Maximum call stack size exceeded

有人知道那里出了什么问题吗?

【问题讨论】:

  • 这意味着您正在经历无限递归,尽管在查看代码之后它并不是立即显而易见(至少对我而言)......由于所有变量,它也有点难以理解跟踪你正在做的事情。
  • 它们是嵌套回调,我看不出递归是怎么可能的......
  • 它几乎必须是最后一次调用 res.json(... 否则你会在 devtools 中一遍又一遍地看到 'here' 打印,直到你得到溢出调用堆栈的错误......除非它发生在某个地方在你没有发布的代码中。
  • 我的测试显示在post.folders.push(folder);之后无法显示日志
  • 嘿 SoftTimur 我发现了一些有类似问题的帖子。 stackoverflow.com/questions/16810449/… '未处理的错误事件'对我来说指向您如何处理未解决的回调。 stackoverflow.com/questions/5384526/javascript-node-js-next 编写 return next() 而不是 return next(err) 有助于错误处理吗?

标签: javascript node.js mongoose mongoose-schema mongoose-populate


【解决方案1】:

下面的代码完成了我想要的。显然,req.post.folders.push(folder) 可以将folder 推送到最新 post。最后我们会做populate。

router.post('/posts/:post/editor/folders', auth, function (req, res, next) {
    var folder = new Folder(req.body);
    folder.post = req.post;
    folder.save(function (err, folder) {
        if (err) return next(err);
        req.post.folders.push(folder);
        req.post.save(function (err, post) {
            if (err) return next(err);
            req.post.populate('folders', function (err, post) {
                if (err) return next(err);
                res.json(post);
            })
        })
    })
});

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 1970-01-01
    • 2021-05-30
    • 2021-07-11
    • 2019-07-05
    • 2015-04-26
    • 2014-06-11
    相关资源
    最近更新 更多