2017-10-07 135 views
0

我正在製作一個基於Web的工具,掛鉤到一個名爲RetroPie-Setup的現有基於shell的框架。NodeJS隊列多個execFile調用

他們有一個名爲/RetroPie-Setup/retropie_packages.sh的shell腳本,您可以使用它來安裝,獲取依賴關係,甚至編譯不同的程序。

一個問題是packages.sh不應該在給定的時刻運行多次,所以我需要設置一個一次運行一個的隊列。

我想我可以使用promise-queue來防止多次執行,但是每當我運行execFile時,它都會立即運行該命令,而不是在它到達隊列中的某個位置時運行該命令。

這裏是我的示例代碼:

downloadTest.sh(下載一個10Mb的文件具有唯一名稱):

filename=test$(date +%H%M%S).db 
wget -O ${filename} speedtest.ftp.otenet.gr/files/test10Mb.db 
rm ${filename} 

節點編號

const Queue = require('promise-queue') 
const { spawn,execFile } = require('child_process'); 
var maxConcurrent = 1; 
var maxQueue = Infinity; 
var que = new Queue(maxConcurrent, maxQueue); 

var testFunct = function(file) 
{ 
    var promise = new Promise((reject,resolve) => { 
     execFile(file,function(error, stdout, stderr) { 
      console.log('Finished executing'); 
      if(error) 
      { 
       reject(); 
      } else 
      { 
       resolve(stdout); 
      } 
     }); 
    }) 
    return promise; 
} 
var test1 = testFunct('/home/pi/downloadTest.sh') 
var test2 = testFunct('/home/pi/downloadTest.sh') 
var test3 = testFunct('/home/pi/downloadTest.sh') 
que.add(test1); 
que.add(test2); 
que.add(test3); 

回答

1

你的代碼是非常接近工作。主要的問題是你正在執行testFunct(),它反過來返回一個Promise,立即開始執行裏面的內容。要解決這個問題,您可以使用Function.prototype.bind()將參數綁定到函數而不執行它。就像這樣:

que.add(testFunct.bind(null, '/home/pi/downloadTest.sh')); 
que.add(testFunct.bind(null, '/home/pi/downloadTest.sh')); 
que.add(testFunct.bind(null, '/home/pi/downloadTest.sh')); 

或者您可以使用async/await這使得隊列微不足道的實施,這反過來又可以讓你砸promise-queue的依賴。

const execFile = require("util").promisify(require("child_process").execFile) 

(async function() { 
    let scripts = [ 
    "/home/pi/downloadTest.sh", 
    "/home/pi/downloadTest.sh", 
    "/home/pi/downloadTest.sh" 
    ] 

    for (let script of scripts) { 
    try { 
     let { stdout, stderr } = await execFile(script) 
     console.log("successfully executed script:", script) 
    } catch (e) { 
     // An error occured attempting to execute the script 
    } 
    } 
})() 

上面代碼中有趣的部分是await execFile(script)。當您使用await表達式時,整個函數的執行會暫停,直到execFile函數返回的Promise解析或拒絕爲止,這意味着您有一個按順序執行的隊列。