使用 Node.js 发送简单数据的正确方法
Correct method to send simple data using Node.js
我已经使用 express(WebStorm 默认设置)设置了一个基本的 Node.js 服务器,并尝试根据请求(从 pebble watch)将其制作成 运行 一个 python 脚本, 并以
的形式发送返回的 json
{"willCollide": 1, "time": 6000, "strength": "NA"}
回到手表。我刚刚开始研究 JavaScript,所以经验很少,并且预计我做错了大部分事情。
目前我遇到 "Error: can't set headers after they are sent" 并且想知道根据请求向用户发送 json 的正确方法是什么?
我还想知道这是否确实是将数据从 python 脚本发送到 Pebble 手表的最佳方法。
以下是根据请求调用的 JavaScript 文件中的代码:
var express = require('express');
var router = express.Router();
var PythonShell = require('python-shell');
var options = {
mode: 'json'
};
var rain_data;
function run_py_script(data){
var pyshell = new PythonShell('dummy.py', options);
var ret_val;
/* Dummy data doesnt matter atm */
pyshell.send("dummy data"); // change to data
pyshell.on('message', function(message){
console.log(message);
ret_val = message;
console.log(message["willCollide"]); // debug check
});
pyshell.end(function(err){
if (err) {
console.log('error received from python script');
}
console.log('finished script');
});
return ret_val;
}
/* GET rain_track data. */
router.get('/', function(req, res, next) {
rain_data = run_py_script(null);
res.write(rain_data);
res.end();
});
module.exports = router;
您似乎在异步执行方面遇到了问题。
您的函数 run_py_script(data)
在触发 end
事件之前不会 return 最终值。然后,您将能够 return 将响应返回给用户。
这里有两种可能的解决方案:
- 回调
- 承诺
我将使用回调
首先,run_py_script
将有 2 个参数,data
和一个要随响应调用的函数,我们称它为 cb
。 cb
最终会调用最终数据。
function run_py_script(data, cb) {
// I'm going to summarize this code
var ret_val;
pyshell.on('message', function(message){
ret_val = message;
});
pyshell.end(function(err){
return err ? cb(null) : cb(ret_val);
});
// note there is no return statement
}
现在,让我们创建您的控制器:
router.get('/', function(req, res, next) {
run_py_script(null, function(rain_data) {
res.json(rain_data); // same as write().end() but more elegant
});
});
最终奖励: cb
的节点约定是一个 2 个参数的函数;第一个参数曾经是一个错误,如果一切正常,它将是 null
,第二个参数是数据本身,如果错误,它将是 null
。
考虑到这一点,最终代码将是(总结)
function run_py_script(data, cb) {
// ...
pyshell.end(function(err){
return err ? cb(err, null) : cb(null, ret_val);
});
}
run_py_script(null, function(err, rain_data){
if (err){ return res.json(null); }
return res.json(data);
});
我已经使用 express(WebStorm 默认设置)设置了一个基本的 Node.js 服务器,并尝试根据请求(从 pebble watch)将其制作成 运行 一个 python 脚本, 并以
的形式发送返回的 json{"willCollide": 1, "time": 6000, "strength": "NA"}
回到手表。我刚刚开始研究 JavaScript,所以经验很少,并且预计我做错了大部分事情。 目前我遇到 "Error: can't set headers after they are sent" 并且想知道根据请求向用户发送 json 的正确方法是什么? 我还想知道这是否确实是将数据从 python 脚本发送到 Pebble 手表的最佳方法。 以下是根据请求调用的 JavaScript 文件中的代码:
var express = require('express');
var router = express.Router();
var PythonShell = require('python-shell');
var options = {
mode: 'json'
};
var rain_data;
function run_py_script(data){
var pyshell = new PythonShell('dummy.py', options);
var ret_val;
/* Dummy data doesnt matter atm */
pyshell.send("dummy data"); // change to data
pyshell.on('message', function(message){
console.log(message);
ret_val = message;
console.log(message["willCollide"]); // debug check
});
pyshell.end(function(err){
if (err) {
console.log('error received from python script');
}
console.log('finished script');
});
return ret_val;
}
/* GET rain_track data. */
router.get('/', function(req, res, next) {
rain_data = run_py_script(null);
res.write(rain_data);
res.end();
});
module.exports = router;
您似乎在异步执行方面遇到了问题。
您的函数 run_py_script(data)
在触发 end
事件之前不会 return 最终值。然后,您将能够 return 将响应返回给用户。
这里有两种可能的解决方案:
- 回调
- 承诺
我将使用回调
首先,run_py_script
将有 2 个参数,data
和一个要随响应调用的函数,我们称它为 cb
。 cb
最终会调用最终数据。
function run_py_script(data, cb) {
// I'm going to summarize this code
var ret_val;
pyshell.on('message', function(message){
ret_val = message;
});
pyshell.end(function(err){
return err ? cb(null) : cb(ret_val);
});
// note there is no return statement
}
现在,让我们创建您的控制器:
router.get('/', function(req, res, next) {
run_py_script(null, function(rain_data) {
res.json(rain_data); // same as write().end() but more elegant
});
});
最终奖励: cb
的节点约定是一个 2 个参数的函数;第一个参数曾经是一个错误,如果一切正常,它将是 null
,第二个参数是数据本身,如果错误,它将是 null
。
考虑到这一点,最终代码将是(总结)
function run_py_script(data, cb) {
// ...
pyshell.end(function(err){
return err ? cb(err, null) : cb(null, ret_val);
});
}
run_py_script(null, function(err, rain_data){
if (err){ return res.json(null); }
return res.json(data);
});