node.js - 在node.js/mongoDB中更新时发送后无法设置 header

标签 node.js mongodb

我是 MEAN 堆栈新手,正在尝试使用 Node.js 的 MongoDB 驱动程序在循环中执行多个更新。

当尝试通过此调用迭代下面的记录时,我收到“发送后无法设置 header ”,大概是因为在循环的每个后续迭代中调用并再次调用“next”。

data.sortManual(manualSlug, proposedSortOrder, function(err) {
    if (err) {
        res.send(400, "Failed to update sort order");
    } else {
        res.send(200);
    }
});

如果有人可以帮助我理解我做错了什么,我将非常感激。

sortManual 方法如下:

manualData.sortManual = function(manualSlug, proposedSortOrder, next) {
    database.getDb(function(err, db) {
        if (!err) {
            var arrSortOrder = proposedSortOrder.split(',');

            for (var i = 0; i < arrSortOrder.length; i++) {

                arrSortOrder[i] = arrSortOrder[i].replace(/^\s*/, "").replace(/\s*$/, ""); // trim whitespace

                db.manuals.findAndModify({
                    slug: manualSlug,
                    "topics": {
                        "$elemMatch": {
                            "slug": arrSortOrder[i]
                        }
                    }
                }, [
                    ['_id', 'asc']
                ], {
                    $set: {
                        "topics.$.sort": i
                    }
                }, {
                    new: false,
                    upsert: true
                }, function(err, result) { <-- I probably shouldn't be doing this on each iteration of the loop but where to handle this?
                    if (err) {
                        console.log(err);
                        next(err, null);
                    } else {
                        console.log(result);
                        next(null, result);
                    }
                });
            } // end loop              
        } // end if
    }); // end getDb
}; // end sortManual

最佳答案

与MongoDB无关,而是HTTP协议(protocol)。

错误消息告诉您 HTTP header 被设置了多次,根据协议(protocol)定义这是不可能的。 (注意:我们谈论的是响应,与 Mongo 内部发生的情况无关)

问题在于回调next(发送 header 的回调)被执行了多次。

如果您查看代码,您会注意到有一个 for 循环,并且 next 在每个循环步骤中用作回调 - 因此我们有问题。

解决方案

您必须重构代码以仅执行一次next,这可以通过 basic counting example 来完成:

        var counter = arrsortOrder.length;
        var errors = [];
        function checkIfLast(err) {
           if(err)   {
              errors.push(err);
           }
           counter--;
           if(counter == 0)  {
             if(errors.length > 0)
                next(errors.join());
             else
                next();
           }
        }
        for (var i = 0; i < arrSortOrder.length; i++) {

            arrSortOrder[i] = arrSortOrder[i].replace(/^\s*/, "").replace(/\s*$/, ""); // trim whitespace

            db.manuals.findAndModify({
                slug: manualSlug,
                "topics": {
                    "$elemMatch": {
                        "slug": arrSortOrder[i]
                    }
                }
            }, [
                ['_id', 'asc']
            ], {
                $set: {
                    "topics.$.sort": i
                }
            }, {
                new: false,
                upsert: true
            }, function(err, result) { <-- I probably shouldn't be doing this on each iteration of the loop but where to handle this?
                if (err) {
                    checkIfLast(err);
                    console.log(err);
                    next(err, null);
                } else {
                    checkIfLast();
                    console.log(result);
                    next(null, result);
                }

关于node.js - 在node.js/mongoDB中更新时发送后无法设置 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28341394/

相关文章:

javascript - 处理订单队列 (Redis) 的最佳选择是什么?

c++ - 对符号 X509_free 的 undefined reference

mongodb - 如何找到导致 bson.errors.InvalidStringData 的值

json - 添加关系时的环回问题

javascript - 将两个客户端数据保存到一个变量中?

node.js - 在 Jenkins CI 和 Debian 上使用 ChromeHeadless 的 Karma

javascript - mongoose 不通过 ID 更新模型

mongodb后台任务

testing - 与 Node.js 一起使用的最佳测试框架是什么?

javascript - buffer是什么数据格式?