我是一个MEAN堆栈新手,我正在尝试使用MongoDB驱动程序为node.js在循环中执行多个更新。
当尝试通过此调用迭代下面的记录时,我收到'无法在发送后设置标头',大概是因为调用'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
答案 0 :(得分:2)
它与MongoDB无关,而与HTTP协议无关。
错误消息告诉您HTTP标头被多次设置,这根据协议定义是不可能的。 (注意:我们正在讨论回应,并不重要的是Mongo内部发生的事情)。
问题在于回调next
(发送标题的那个)被执行多次。
如果您查看代码,您会注意到有一个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);
}