0

Express (WebStorm のデフォルト) を使用して基本的な Node.js サーバーをセットアップし、要求に応じて (pebble watch から) python スクリプトを実行し、返された json を次の形式で送信しようとしました。

{"willCollide": 1, "time": 6000, "strength": "NA"}

時計に戻ります。私は JavaScript を調べ始めたばかりなので、経験がほとんどなく、これのほとんどを間違って行っていると予想されます。現在、「エラー: 送信後にヘッダーを設定できません」というメッセージが表示され、リクエスト時に 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;
4

1 に答える 1

0

非同期実行に問題があるようです。

イベントが発生するまで、関数run_py_script(data)は最終的な値を返しません。endその後、応答をユーザーに返すことができます。
ここでは、2 つの解決策が考えられます。

  1. コールバック
  2. 約束

コールバックを使ってアプローチしていきます

まず、run_py_script2 つの引数がdataあり、応答で呼び出される関数があるので、それを呼び出しましょうcbcb最終的なデータで最終的に呼び出されます。

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、すべて問題ありません。2 番目の引数はデータ自体で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);
});
于 2016-07-27T13:23:48.033 に答える