2017-10-07 136 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解析或拒绝为止,这意味着您有一个按顺序执行的队列。