2016-05-20 9 views
1

Ein Atom-Paket von mir öffnet eine Datei im Standard-Datei-Manager des Systems. Unter Linux habe ich eine Reihe von weit verbreiteten Datei-Managern, die ich über den which-Befehl ausführen und den Pfad zurückgeben möchte.Node.js: Iterating welcher Befehl über ein Array von Binärdateien

Das Problem mit meinem aktuellen Skript ist, dass ich nicht weiß, wie man die Iteration bricht. Das Ausführen dieses Codes protokolliert alle which Versuche und führt zu jeder verfügbaren Option. Offensichtlich ist dies nicht der Zweck der Iteration.

Coffee (JavaScript unten):

fileManagers: ['xdg-open', 'gnome-open', 'kde-open', 'nautilus', 'dolphin']  

@loopWhich (result) -> 
    console.log "Result: #{result}"  

loopWhich: (callback) -> 
    {exec} = require('child_process') 

    for fm in @fileManagers  

     console.log "which: #{fm}"  

     exec "which #{fm}", (error, stdout, stderr) -> 
     if error is null 
      callback stdout 

JavaScript (automatisch generiert durch [email protected]):

({ 
    fileManagers: ['xdg-open', 'gnome-open', 'kde-open', 'nautilus', 'dolphin'] 
});  

this.loopWhich(function(result) { 
    return console.log("Result: " + result); 
});  

({ 
    loopWhich: function(callback) { 
    var exec, fm, i, len, ref, results; 
    exec = require('child_process').exec; 
    ref = this.fileManagers; 
    results = []; 
    for (i = 0, len = ref.length; i < len; i++) { 
     fm = ref[i]; 
     console.log("which: " + fm); 
     results.push(exec("which " + fm, function(error, stdout, stderr) { 
     if (error === null) { 
      return callback(stdout); 
     } 
     })); 
    } 
    return results; 
    } 
}); 

Antwort

0

Seine wegen der Asynchron-Aspekt hart, aber ich denke, das sollte Arbeit:

{exec} = require 'child_process' 

promisify = (name, fn, args...) -> 
    return new Promise (resolve, reject) -> 
    cb = (err) -> if err then reject err else resolve name 
    fn.apply null, args.concat(cb) 

thenHandler = (name) -> console.log name 

fileManagers.forEach (filem) -> promisify(filem, exec, "which #{filem}").then thenHandler 

Die Fehlerfälle werden ignoriert, und eine erfolgreiche Ausführung sollte auf der Konsole protokolliert werden. Wenn Sie die tatsächliche erfolgreich wollen, müssen Sie all die Versprechungen in ein anderes Versprechen wickeln und einen anderen .then Handler verwenden, um die übergreifende Versprechen mit dem richtigen Ergebnis zu beheben:

fileManager = new Promise (resolve, reject) -> 
    fileManagers.forEach (filem) -> 
    promisify(filem, exec, "which #{filem}").then (name) -> resolve name 

Wenn mehr als ein Versuch ist erfolgreich, es wird nur mit dem ersten lösen.