在node.js / mongoDB中更新时,无法设置标头
我是一个MEAN堆栈新手,并试图在一个循环中使用Node.js的MongoDB驱动程序执行多个更新。
当试图通过这个调用遍历下面的logging时,我收到'发送后无法设置标题',大概是因为在循环的每个子循环迭代中都会调用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协议。
错误消息告诉你HTTP标头被设置了多次,根据协议定义是不可能的。 (注意:我们正在谈论响应,无论Mongo内部发生了什么) 。
问题在于next
一个callback(发送头文件)多次执行。
如果你看看你的代码,你会注意到有一个for
循环, next
被用作每个循环步骤的callback – 因此我们遇到了问题。
解
你必须重构代码才能执行next
一次,这可以通过基本的计数例子来完成:
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); }