電子冒険:エピソード16:ストリーミング端末出力


私たちのターミナルのアプリの最大の制限に対処しましょう-それは現在、コマンドが出力を表示する前に終了するのを待ちます.
我々は、エピソード15からCodeBaseから起動し、ストリーミング機能を追加します.

約束とコールバック


ノードAPIは約束を使用しません.我々はラップすることができたchild_process.exec 約束で、私たちはちょうどそれが終わるのを待つことができたので、すぐに結果をすべて届けます.
let runCommand = (command) => {
  return new Promise((resolve, reject) => {
    child_process.exec(command, (error, stdout, stderr) => {
      resolve({stdout, stderr, error})
    })
  })
}
残念ながら、これを取り消しなければなりません.約束は非常に便利です、しかし、彼らの全体の点は彼らがすぐに彼らの結果(またはエラー)を届けるということです、そして、彼らはされます.

プリロードでruncommand。js


そして、もう一度我々はコマンドを実行する方法を変更します.最初に使用child_process.execSync , then child_process.exec , そして今、我々はchild_process.sync .
let runCommand = ({command, onout, onerr, ondone}) => {
  const proc = child_process.spawn(
    command,
    [],
    {
      shell: true,
      stdio: ["ignore", "pipe", "pipe"],
    },
  )
  proc.stdout.on("data", (data) => onout(data.toString()))
  proc.stderr.on("data", (data) => onerr(data.toString()))
  proc.on("close", (code) => ondone(code))
}

contextBridge.exposeInMainWorld(
  "api", { runCommand }
)
これは次のようになります.
  • stdinを接続する/dev/null , それで、我々が走らせるコマンドは、これまでに来ることができない入力を待っていません
  • stdoutとstderrをコールバックに接続するonout and onerr ; データをバイナリとして受け取りますので、
  • 呼び出し元ondone コマンドが終了すると終了コードは0から255まで、0は成功を意味します、そして、他のすべての値はコマンドの間で完全に矛盾している方法で様々なエラーを意味します
  • 使用するshell: true シェルを通してコマンドを実行するために、パイプやリダイレクションなどのシェルのすべてを使用することができます.
  • 新しいインターフェイス


    我々は、UIコード内の任意の変更を行う必要はありません.ジャストチェンジonsubmit 新しいインターフェイスを使用するハンドラ
      async function onsubmit(command) {
        let entry = {command, stdout: "", stderr: "", error: null, running: true}
        history.push(entry)
        history = history
        let onout = (data) => {
          entry.stdout += data
          history = history
        }
        let onerr = (data) => {
          entry.stderr += data
          history = history
        }
        let ondone = (code) => {
          entry.running = false
          entry.error = (code !== 0)
          history = history
        }
        window.api.runCommand({command,onout,onerr,ondone})
      }
    
    前と同じように、畳み込まれた機能スタイルの代わりにhistory 配列を右側の部分を直接変更し、sveltehistory = history .

    結果


    結果は以下の通りです.

    次のエピソードでは、生成されたコマンドと対話する方法を追加します.
    いつものように.all the code for the episode is here .