2016-07-27 5 views
0

Ich habe einen grundlegenden Node.js Server mit Express (WebStorm Standard) eingerichtet, und habe versucht, es auf Anfrage (von einem Pebble Watch) zu machen, ein Python-Skript und senden Sie die zurückgegebene JSON in der Form:Korrekte Methode zum Senden von einfachen Daten mit Node.js

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

zurück auf die Uhr. Ich habe gerade angefangen, in JavaScript zu schauen, also habe sehr wenig Erfahrung und würde erwarten, dass ich das meiste davon falsch mache. Derzeit erfahre ich einen "Fehler: kann Header nicht festlegen, nachdem sie gesendet werden" und fragte mich, was die richtige Methode ist, einen JSON an einen Benutzer auf eine Anfrage zu senden? Ich frage mich auch, ob dies in der Tat die beste Methode ist, um die Daten vom Python-Skript an eine Pebble-Uhr zu senden. Unten ist der Code in der JavaScript-Datei auf der Anfrage genannt werden:

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; 
+0

Welche Version von Express werden verwenden Sie? –

Antwort

0

Scheinen Sie Probleme mit dem asynchronen Ausführung haben.

Ihre Funktion run_py_script(data) gibt den endgültigen Wert nicht zurück, bis das Ereignis end ausgelöst wird. Dann können Sie die Antwort an den Benutzer zurückgeben.
Hier haben Sie zwei mögliche Lösungen:

  1. Rückrufe
  2. Promises

Ich werde einen Ansatz machen mit einem Rückruf

Zunächst wird run_py_script 2 Argumente haben, data und eine Funktion, die mit der Antwort aufgerufen werden soll, nennen wir es cb. cb wird schließlich mit den endgültigen Daten aufgerufen werden.

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 
} 

Nun lassen Sie uns Ihren Controller erstellen:

router.get('/', function(req, res, next) { 
    run_py_script(null, function(rain_data) { 
     res.json(rain_data); // same as write().end() but more elegant 
    }); 
}); 

Schlussbonus: Der Knoten Konvention für cb ist ein 2 Argumente Funktion zu sein; das erste Argument verwendet, um ein Fehler zu sein, der null sein wird, ist alles in Ordnung, und das zweite Argument ist die Daten selbst, die null wenn Fehler sein wird.

In diesem Sinne wäre der endgültige Code (zusammenfassend)

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); 
}); 
+0

Vielen Dank, es hat perfekt funktioniert – Tardis50