2017-09-15 42 views
0

使用節點子進程exec,我通過承諾花費一點時間調用ffmpeg轉換。每次使用點擊「下一步」就上了一個新文件開始ffmpeg的命令:殺死未解決的承諾(或忽略並繼續前進)

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(); 
     } 
    }); 
    }); 
} 

問題是,如果用戶移動到返回的承諾之前,下一個視頻,我需要報廢處理並繼續轉換下一個視頻。

我怎麼可以:

A)(理想)取消當前的承諾EXEC進程* B)讓電流承諾EXEC過程完成,只是忽略了希望,而我開始一個新的。

*我意識到promise.cancel is not yet in ECMA,但我想知道的解決方法 - 最好不使用第三方模塊/庫。

嘗試:

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(); 
     } 
    }); 
    }); 
} 

回答

1

如果我理解正確的話,你想在一個鏈執行的ffmpeg轉換,一前一後,並在移動到下一個,如果處於活動狀態不是招」殺處於活動狀態尚未完成。

假設使用childprocess.exec(),您可以跟蹤全局變量中的子進程,並且在調用doFFMpeg()時,在實例化新promise之前,應該有kill()任何運行。

1

假設exec()確實使用.kill()方法返回對象,該嘗試看起來非常接近您想要的。您只需接受承諾拒絕來取代原有承諾中不可用的取消。拒絕而不是取消通常是無關緊要的,甚至更好。

據我所知,殺死進程會導致回調觸發錯誤,(和/或'退出'處理程序與錯誤代碼觸發)。如果是這樣,當進程被終止時,您不需要明確拒絕承諾 - 無論如何將會調用reject()

您的doFFMpeg()只需要一些安全的電話myChildProcess.kill()

像這樣的東西應該這樣做:

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; 
      }); 
     }); 
    } 
})(); 

我不知道該exec()的回調是必要的(除非你需要處理stdout/stderr或需要知道error的細節)。可能只需要.on('exit')處理程序就足夠了,或者可能是.on('end').on('error')處理程序。

如果調用者需要處理「殺死錯誤」與其他錯誤不同,那麼還有一點工作要做。您需要確保在殺死時,Promise被拒絕並出現可檢測到的錯誤(例如,自定義錯誤或使用自定義屬性monkeypatched的錯誤)。