簡體   English   中英

如何正確地連續調用Node.js中的子進程?

[英]How do I correctly make consecutive calls to a child process in Node.js?

我有一個Node.js應用程序,該應用程序當前是基於Web的API。 對於我的API函數之一,我調用了一個簡短的Python腳本,該腳本是為實現某些額外功能而編寫的。

在閱讀完使用child_process模塊進行的Node和Python之間的通信后,我嘗試了一下並取得了期望的結果。 我調用接收電子郵件地址的Node函數,並通過std.in將其發送到Python,我的Python腳本使用提供的電子郵件執行必要的外部API調用,並將外部API調用的輸出寫入std.out並將其發送回我的Node函數。

一切正常,直到我連續發出多個請求。 盡管Python的正確記錄更改的電子郵件地址,並發出請求,將更新的電子郵件地址的外部API,第一個請求我讓我的 API后(返回正確的數據),我不斷收到相同的舊數據一次又一次。

我最初的猜測是沒有清除Python的輸入流,但是在測試Python腳本之后,我看到我正在正確地更新從Node接收的電子郵件地址並接收正確的查詢結果。

我認為child_process模塊​​的某些基礎工作可能我不了解...因為我相當確定相應的數據已正確地來回傳遞。

下面是Node函數:

exports.callPythonScript = (email)=>
{
    let getPythonData = new Promise(function(success,fail){

    const spawn = require('child_process').spawn;
    const pythonProcess = spawn('python',['./util/emailage_query.py']);

    pythonProcess.stdout.on('data', (data) =>{
      let dataString = singleToDoubleQuote(data.toString());
      let emailageResponse = JSON.parse(dataString);
      success(emailageResponse);
    })

    pythonProcess.stdout.on('end', function(){
      console.log("python script done");
    })

    pythonProcess.stderr.on('data', (data) => {
      fail(data);
    })

    pythonProcess.stdin.write(email);
    pythonProcess.stdin.end();

    })

    return getPythonData;

  }

這是Python腳本:

import sys
from emailage.client import EmailageClient

def read_in():
    lines = sys.stdin.readlines()
    return lines[0]

def main():
    client = EmailageClient('key','auth')
    email = read_in()
    json_response = client.query(email,user_email='authemail@mail.com')
    print(json_response)
    sys.stdout.flush()

if __name__ == '__main__':
    main()

同樣,在單次調用callPythonScript一切都會完美返回。 只有在進行多次調用時,我才能一遍又一遍地返回相同的輸出。

我在這里碰壁,任何幫助都將不勝感激。 謝謝大家!

在這種示例中,我使用了互斥鎖。 我似乎找不到代碼的問題,因為當我遇到類似問題時,我在SO上發現了它:

class Lock {
  constructor() {
    this._locked = false;
    this._waiting = [];
  }

  lock() {
    const unlock = () => {
      let nextResolve;
      if (this._waiting.length > 0) {
        nextResolve = this._waiting.pop(0);
        nextResolve(unlock);
      } else {
        this._locked = false;
      }
    };
    if (this._locked) {
      return new Promise((resolve) => {
        this._waiting.push(resolve);
      });
    } else {
      this._locked = true;
      return new Promise((resolve) => {
        resolve(unlock);
      });
    }
  }
}

module.exports = Lock;

然后我調用的地方將使用您的代碼來實現它:

class Email {
  constructor(Lock) {
    this._lock = new Lock();
  }

  async callPythonScript(email) {
    const unlock = await this._lock.lock();
    let getPythonData = new Promise(function(success,fail){

    const spawn = require('child_process').spawn;
    const pythonProcess = spawn('python',['./util/emailage_query.py']);

    pythonProcess.stdout.on('data', (data) =>{
      let dataString = singleToDoubleQuote(data.toString());
      let emailageResponse = JSON.parse(dataString);
      success(emailageResponse);
    })

    pythonProcess.stdout.on('end', function(){
      console.log("python script done");
    })

    pythonProcess.stderr.on('data', (data) => {
      fail(data);
    })

    pythonProcess.stdin.write(email);
    pythonProcess.stdin.end();

    })
    await unlock();
    return getPythonData;
  }
}

我尚未測試此代碼,並且已經實現了在處理數組和調用python的每個數組值的地方……但這至少應該為您提供一個良好的開端。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM