2017-09-15 1 views
0

Mit Knoten Kind Prozess exec, rufe ich eine ffmpeg Umwandlung über ein Versprechen, das ein wenig Zeit braucht. Jedes Mal, wenn die Verwendung Klicks „next“ den FFMpeg Befehl in einer neuen Datei beginnt:Kill ein nicht gelöstes Versprechen (oder ignorieren und weitermachen)

function doFFMpeg(path){ 
    return new Promise((resolve, reject) => { 
    exec('ffmpeg (long running command)', (error, stdout, stderr) => { 
     if (error) { 
     reject(); 
     } 
    }).on('exit', (code) => { // Exit returns code 0 for good 1 bad 
     if (code) { 
     reject(); 
     } else { 
     resolve(); 
     } 
    }); 
    }); 
} 

Das Problem ist, wenn der Benutzer zum nächsten Video bewegt sich auf, bevor das Versprechen zurückgegeben wird, muß ich den Prozess Schrott und gehe zum nächsten Video über.

Wie kann ich entweder:

A) (Im Idealfall den aktuellen versprach exec Prozess * B) Lassen Sie Abbrechen) der aktuelle exec Prozess abgeschlossen versprochen, aber einfach ignorieren dieses Versprechen, während ich eine neue zu starten.

* Ich realisiere, dass promise.cancel is not yet in ECMA, aber ich möchte eine Problemumgehung wissen - vorzugsweise ohne Verwendung eines 3rd-Party-Modul/Bibliothek.

Versuch:

let myChildProcess; 

function doFFMpeg(path){ 

    myChildProcess.kill(); 

    return new Promise((resolve, reject) => { 
    myChildProcess = exec('ffmpeg (long running command)', (error, stdout, stderr) => { 
     if (error) { 
     reject(); 
     } 
    }).on('exit', (code) => { // Exit returns code 0 for good 1 bad 
     if (code) { 
     reject(); 
     } else { 
     resolve(); 
     } 
    }); 
    }); 
} 

Antwort

1

Wenn ich das richtig verstanden, Sie ffmpeg Umwandlungen in einer Kette, einer nach dem anderen, und töten die aktiven beim Bewegen auf die nächste, wenn die aktive hasn ausführen möchten‘ Ich bin noch nicht fertig.

Unter der Annahme, childprocess.exec() verwendet wird, können Sie den Überblick über die untergeordneten Prozesse in einer globalen Variablen halten konnte und wenn doFFMpeg() aufgerufen wird, sollte es kill() jeder läuft noch bevor das neue Versprechen instanziieren.

1

Angenommen exec() gibt in der Tat ein Objekt mit einer .kill() Methode zurück, der Versuch sieht ziemlich genau aus, was Sie wollen. Sie müssen nur die Ablehnung des Versprechens anstelle der Stornierung akzeptieren, die in den einheimischen Promises nicht verfügbar ist. Es ist in der Regel unwichtig, noch besser, abzulehnen als abzubrechen.

Wie ich es verstehe, wird das Löschen des Prozesses verursachen, dass der Rückruf mit einem Fehler ausgelöst wird (und/oder der 'Exit'-Handler mit dem Fehlercode ausgelöst wird). Wenn dies der Fall ist, müssen Sie das Versprechen nicht explizit ablehnen, wenn der Prozess beendet wird - reject() wird trotzdem aufgerufen.

Ihre doFFMpeg() braucht nur etwas Sicherheit um myChildProcess.kill() anrufen.

So etwas sollte es tun:

const doFFMpeg = (function() { 
    var myChildProcess = null; 
    return function (path) { 
     if (myChildProcess) { 
      myChildProcess.kill(); 
     } 
     return new Promise((resolve, reject) => { 
      myChildProcess = exec('ffmpeg (long running command)', (error, stdout, stderr) => { 
       if (error) { 
        reject(error); 
       } 
       myChildProcess = null; 
      }); 
      myChildProcess.on('exit', (code) => { // Exit returns code 0 for good 1 bad 
       if (code) { 
        reject(new Error('bad exit')); 
       } else { 
        resolve(); 
       } 
       myChildProcess = null; 
      }); 
     }); 
    } 
})(); 

Ich bin nicht sicher, dass exec() ‚s Rückruf erforderlich ist (es sei denn, Sie stdout/stderr oder müssen verarbeiten müssen Details des error kennen). Es ist möglich, dass nur der Handler .on('exit') genügt, oder vielleicht .on('end') und .on('error') Handler.

Wenn der Aufrufer "Kill-Fehler" anders als andere Fehler behandeln muss, dann gibt es ein wenig mehr Arbeit zu tun. Sie müssen sicherstellen, dass beim Kill das Versprechen mit einem erkennbaren Fehler (z. B. einem benutzerdefinierten Fehler oder einem Fehler, der mit einer benutzerdefinierten Eigenschaft übereinstimmt) zurückgewiesen wird.

Verwandte Themen