2017-04-19 280 views
1

我想執行這段執行python腳本的節點js代碼。通過這段代碼工作正常。但是「前進」和「結束」的響應立即顯示在前端。一旦python腳本的執行完成,就必須顯示「finshed」。通過nodejs執行python腳本

app.post('/execute', function(request, response){ 
    response.write("running"); 
    console.log("executing") 
    var pyshell = new PythonShell('./python_codes/test.py') 
    pyshell.on('message', function (message) {console.log(message);}); 
    pyshell.end(function (err) {if (err){throw err;};console.log('finished');}); 
    response.write("finished"); 
    response.end(); 
}); 
+0

'PythonShell'內使用你的反應'child_process.spawn',這是異步的 - 你在這裏說「快跑這條巨蟒的事情,當告訴我它是通過使用'.end'給出的回調完成的,而當你這樣做時,我將繼續使用我自己的東西。「我懷疑你需要等待'pyshell.terminated'來顯示正確的值,或者將響應傳遞給'.end'回調 –

+0

@SimonFraser完整的代碼未顯示,因此HTTP庫是否支持這是可能的(甚至可能),一旦'app.post'回調完成,'response.end()'將被隱式調用。 –

+1

@FredrickBrennan公平點:)我比節點更蟒蛇,所以我試圖去看看PythonShell的東西了 –

回答

1

您應該添加回調函數

app.post('/execute', function(request, response){ 

    response.setHeader('Connection', 'Transfer-Encoding'); 
    response.setHeader('Content-Type', 'text/html; charset=utf-8'); 

    response.write("running"); 
    console.log("executing") 
    var pyshell = new PythonShell('./python_codes/test.py') 
    pyshell.on('message', function (message) {console.log(message);}); 
    pyshell.end(function (err) { 
    if (err){ 
     throw err; 
    }; 
    console.log('finished'); 
    response.write("finished"); 
    response.end(); 
    }); 
}); 
+0

我試過了,但它的方法是它也沒有發送「運行」消息。所有的味精都在執行後發送test.py –

+0

Add 'response.setHeader('Connection','Transfer-Encoding');' 'response.setHeader('Content-Type','text/html; charset = utf -8');' 允許瀏覽器立即顯示內容。 – Ezzat

+0

非常感謝您的幫助 –

1

這是因爲PythonShell類是異步的。你的代碼正在做的是創建一個PythonShell對象,將它存儲在變量pyshell中,然後向pyshell對象添加一些事件。然後直接繼續寫「完成」。

因爲寫入「已完成」不是end()函數回調的一部分,所以它會立即發生。我看至少三件事情可以做:

  1. 如果您使用的是HTTP庫支持它,只是response.write("finished"); response.end();代碼添加到pyshell.end回調。
  2. 使用支持暫停當前執行線程的庫(或使用execSync)調用Python。這是不好的做法,因爲它違背了使用像node.js這樣的併發框架的目的,但是會起作用。
  3. 使用WebSockets(或socket.io,即使WebSocket不可用,例如通過CloudFlare也可以)傳輸「已完成」消息。