如何正确地从Node.js API发送响应代码
how to properly send the response code from Node.js API
我有一个简单的基于节点的API,它需要解析一些JSON,将一些数据保存到Postgres中,然后发送适当的响应代码(如http 201)。我的代码是这样的:
router.route('/customer')
.post(function(req, res) {
Customers = req.body;
var numberOfCustomers = Customers.length;
for(var i = 0; i < Customers.length; i++){
Customer = Customers[i];
console.log(Customer.Name + " " + Customer.Address);
var date = moment(new Date()).unix();
client.query(
'INSERT into customer (name, address, date_modified) VALUES($1, $2, $3) RETURNING id',
[Customer.Name, Customer.Address, date],
function(err, result) {
if (err) {
console.log(err);
status = 1;
} else {
console.log('row inserted with id: ' + result.rows[0].id);
if(numberOfCustomers === i) {
res.status(201).send({ message: "created" });
}
}
});
}
})
我得到这个错误:
_
http_outgoing.js:344
throw new Error('Can''t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
我需要考虑的事实是,我在一个循环内执行我的Postgres插入多次,所以我不能在第一次插入完成后发送我的响应头。
在我的'POST'处理程序中放置我的res.status(201).send({ message: "created" });
的最合适的位置是什么div ?
不考虑架构决策(例如,您可能需要一个单独的模块作为HTTP适配器来处理发送响应代码的逻辑,而不是在路由控制器中处理),您可以使用promise等待所有插入完成,然后发送一个单个响应代码。例如,像这样:
var Promise = require('bluebird');
var query = Promise.promisify(client.query);
router.route('/customer')
.post(function(req, res) {
// all your logic, and then
return Promise.all(Customers.map(function() {
return query(sql, [Customer.Name, Customer.Address, date]);
})
.then(function() {
res.status(201).send({ message: 'Created' });
});
});
查看bluebird文档,了解本例中使用的API。
我不熟悉Postgres的API,但概念应该是相似的:你需要等待所有的请求到你的数据库首先被解决
如上所述:是的,async helper(如Promises和async)对这类事情是有益的。然而,我相信解决这个问题的"最佳"方法是只使用单个查询。与其每个查询只执行一次插入,不如将它们全部批处理到单个查询中,如下所示:
INSERT into customer (name, address, date_modified)
VALUES
($1, $2, $3),
($4, $5, $6),
($7, $8, $9),
...
RETURNING id'
建议router.route('/customer').post(function(req, res) {
//Fetch customers
var customers = req.body;
//Store parameters and query inserts for db-query.
var params = [];
var inserts = [];
//For each customer
// - Add parameters for query
// - Build insert string
customers.forEach(function(customer){
inserts.push(
[
"($",
params.push(customer.Name),
", $",
params.push(customer.Address),
", ",
NOW(), //unnecessary to generate timestamp in js
")",
].join('')
)
});
//Build query
var query = 'INSERT into customer (name, address, date_modified) VALUES '+ inserts +' RETURNING id';
//Query database in a more simple fashion.
client.query(query, params, function(err, result) {
if (err) {
console.log(err);
status = 1;
} else {
res.status(201).send({ message: "created" });
});
}
})
如果你使用的是ES6,你可以通过使用字符串模板来简化字符串构建操作。
customers.forEach(function(customer){
var query = `($${params.push(customer.Name)}, $${params.push(customer.Address)}, NOW())`
inserts.push(query);
});
//and
var query = `
INSERT into customer (name, address, date_modified)
VALUES ${inserts}
RETURNING id
`;
正确的做法是,我还建议您查看Async or lodash lib
。
router.route('/customer')
.post(function(req, res) {
var Customers = req.body,
numberOfCustomers = Customers.length;
for(var i = 0; i < Customers.length; i++){
var Customer = Customers[i];
console.log(Customer.Name + " " + Customer.Address);
var date = moment(new Date()).unix(),
sql = 'INSERT into customer (name, address, date_modified) VALUES($1, $2, $3) RETURNING id';
client.query(sql, [Customer.Name, Customer.Address, date],
function(err, result) {
if (err) {
console.log(err);
res.status(500).json({message: "Server Error", err: err});
} else {
console.log('row inserted with id: ' + result.rows[0].id);
if (numberOfCustomers === i) {
res.status(201).send({ message: "Created" });
}
}
});
}
})
相关文章:
- 不再使用innerHTML进行AJAX响应.(代码未得到响应)
- WebSocket握手:意外的响应代码:404
- 如何检索AMD的XHR响应代码(+时间戳)'大型Dojo
- 意外的响应代码426
- 如果我使用html表单(而不是ajax),则获取服务器的响应代码或返回值
- 检查 http 响应代码以显示相应的失败消息
- 在封闭的 python 服务器上的 ajax 请求中获取 0 作为 Http 响应代码
- Node.js使用 Socket.io 的应用程序在OpenShift主机上给出“意外响应代码:400”
- 如何使用 java 脚本获取 httprequest 的响应代码
- 使 $ .ajax 将响应代码 40x 视为成功
- 节点ACS 404未找到Java http客户端的响应代码
- 为什么200 HTTP响应代码上的XmlHttpRequest readyState=2
- PhoneGap/Cordova没有监听401,将http响应代码修改为200不起作用
- 奇怪的AJAX响应代码
- WebSocket握手期间出错:意外的响应代码:500
- 如何在Jquery POST中获得HTTP错误响应代码?
- 为REST端点返回不同的HTTP响应代码
- Html/Javascript中的Http响应代码
- 303响应代码不工作(Stripe Connect with Angular.js)
- 如何获得HTTP响应代码