成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

在 Node.js 中用子進(jìn)程操作標(biāo)準(zhǔn)輸入/輸出

leeon / 500人閱讀

摘要:在行中,我們將子進(jìn)程的連接到當(dāng)前進(jìn)程的。等待子進(jìn)程通過(guò)退出函數(shù)如下所示。子進(jìn)程的實(shí)現(xiàn)以下代碼用異步寫入以命令運(yùn)行的子進(jìn)程的我們?yōu)槊钌梢粋€(gè)名為的獨(dú)立進(jìn)程。而是子進(jìn)程完成。沒(méi)有這個(gè),將會(huì)在調(diào)用之前被輸出。

翻譯:瘋狂的技術(shù)宅
原文:http://2ality.com/2018/05/chi...

本文首發(fā)微信公眾號(hào):jingchengyideng
歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章

在本中,我們?cè)?Node.js 中把 shell 命令作為子進(jìn)程運(yùn)行。然后異步讀取這些進(jìn)程的 stdout 并寫入其 stdin。

在子進(jìn)程中運(yùn)行 shell 命令

首先從在子進(jìn)程中運(yùn)行 shell 命令開始:

const {onExit} = require("@rauschma/stringio");
const {spawn} = require("child_process");

async function main() {
  const filePath = process.argv[2];
  console.log("INPUT: "+filePath);

  const childProcess = spawn("cat", [filePath],
    {stdio: [process.stdin, process.stdout, process.stderr]}); // (A)

  await onExit(childProcess); // (B)

  console.log("### DONE");
}
main();

解釋:

我們用了 spawn(),它可以使我們?cè)诿钸\(yùn)行時(shí)訪問(wèn)命令的 stdin,stdout 和 stderr。

在 A 行中,我們將子進(jìn)程的 stdin 連接到當(dāng)前進(jìn)程的 stdin。

B 行等待該過(guò)程完成。

等待子進(jìn)程通過(guò) Promise 退出

函數(shù) onExit()如下所示。

function onExit(childProcess: ChildProcess): Promise {
  return new Promise((resolve, reject) => {
    childProcess.once("exit", (code: number, signal: string) => {
      if (code === 0) {
        resolve(undefined);
      } else {
        reject(new Error("Exit with error code: "+code));
      }
    });
    childProcess.once("error", (err: Error) => {
      reject(err);
    });
  });
}
子進(jìn)程的實(shí)現(xiàn)

以下代碼用 @rauschma/stringio 異步寫入以 shell 命令運(yùn)行的子進(jìn)程的 stdin

const {streamWrite, streamEnd, onExit} = require("@rauschma/stringio");
const {spawn} = require("child_process");

async function main() {
  const sink = spawn("cat", [],
    {stdio: ["pipe", process.stdout, process.stderr]}); // (A)

  writeToWritable(sink.stdin); // (B)
  await onExit(sink);

  console.log("### DONE");
}
main();

async function writeToWritable(writable) {
  await streamWrite(writable, "First line
");
  await streamWrite(writable, "Second line
");
  await streamEnd(writable);
}

我們?yōu)?shell 命令生成一個(gè)名為 sink 的獨(dú)立進(jìn)程。用 writeToWritable 寫入 sink.stdin。它借助 await 異步執(zhí)行并暫停,以避免緩沖區(qū)被消耗太多。
解釋:

在A行中,我們告訴 spawn() 通過(guò) sink.stdin"pipe")訪問(wèn) stdin。 stdout 和 stderr 被轉(zhuǎn)發(fā)到 process.stdinprocess.stderr,如前面所述。

在B行中不會(huì) await 寫完成。而是 await 子進(jìn)程 sink 完成。

接下來(lái)了解 streamWrite() 的工作原理。

寫流操作的 promise

Node.js 寫流的操作通常涉及回調(diào)(參見文檔)。代碼如下。

function streamWrite(
  stream: Writable,
  chunk: string|Buffer|Uint8Array,
  encoding="utf8"): Promise {
    return new Promise((resolve, reject) => {
      const errListener = (err: Error) => {
        stream.removeListener("error", errListener);
        reject(err);
      };
      stream.addListener("error", errListener);
      const callback = () => {
        stream.removeListener("error", errListener);
        resolve(undefined);
      };
      stream.write(chunk, encoding, callback);
    });
}

streamEnd()的工作方式是類似的。

從子進(jìn)程中讀取數(shù)據(jù)

下面的代碼使用異步迭代(C行)來(lái)讀取子進(jìn)程的 stdout 中的內(nèi)容:

const {chunksToLinesAsync, chomp} = require("@rauschma/stringio");
const {spawn} = require("child_process");

async function main() {
  const filePath = process.argv[2];
  console.log("INPUT: "+filePath);

  const source = spawn("cat", [filePath],
    {stdio: ["ignore", "pipe", process.stderr]}); // (A)

  await echoReadable(source.stdout); // (B)

  console.log("### DONE");
}
main();

async function echoReadable(readable) {
  for await (const line of chunksToLinesAsync(readable)) { // (C)
    console.log("LINE: "+chomp(line))
  }
}

解釋:

A行:我們忽略 stdin,希望通過(guò)流訪問(wèn) stdout 并將 stderr 轉(zhuǎn)發(fā)到process.stderr

B行:開始 awat 直到 echoReadable() 完成。沒(méi)有這個(gè) awaitDONE 將會(huì)在調(diào)用 source.stdout 之前被輸出。

在子進(jìn)程之間進(jìn)行管道連接

在下面的例子中,函數(shù)transform() 將會(huì):

source 子進(jìn)程的 stdout 中讀取內(nèi)容。

將內(nèi)容寫入 sink 子進(jìn)程的 stdin

換句話說(shuō),我們正在實(shí)現(xiàn)類似 Unix 管道的功能:

cat someFile.txt | transform() | cat

這是代碼:

const {chunksToLinesAsync, streamWrite, streamEnd, onExit}
  = require("@rauschma/stringio");
const {spawn} = require("child_process");

async function main() {
  const filePath = process.argv[2];
  console.log("INPUT: "+filePath);

  const source = spawn("cat", [filePath],
    {stdio: ["ignore", "pipe", process.stderr]});
  const sink = spawn("cat", [],
    {stdio: ["pipe", process.stdout, process.stderr]});

  transform(source.stdout, sink.stdin);
  await onExit(sink);

  console.log("### DONE");
}
main();

async function transform(readable, writable) {
  for await (const line of chunksToLinesAsync(readable)) {
    await streamWrite(writable, "@ "+line);
  }
  await streamEnd(writable);
}
擴(kuò)展閱讀

博客:“通過(guò) Node.js 的異步迭代讀取流”

“探索ES2018和ES2019”中的“異步迭代 一章

“探索ES2016和ES2017”中的“異步功能” 一章

歡迎繼續(xù)閱讀本專欄其它高贊文章:

12個(gè)令人驚嘆的CSS實(shí)驗(yàn)項(xiàng)目

世界頂級(jí)公司的前端面試都問(wèn)些什么

CSS Flexbox 可視化手冊(cè)

過(guò)節(jié)很無(wú)聊?還是用 JavaScript 寫一個(gè)腦力小游戲吧!

從設(shè)計(jì)者的角度看 React

CSS粘性定位是怎樣工作的

一步步教你用HTML5 SVG實(shí)現(xiàn)動(dòng)畫效果

程序員30歲前月薪達(dá)不到30K,該何去何從

第三方CSS安全嗎?

談?wù)剆uper(props) 的重要性

本文首發(fā)微信公眾號(hào):jingchengyideng 歡迎掃描二維碼關(guān)注公眾號(hào),每天都給你推送新鮮的前端技術(shù)文章

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/102134.html

相關(guān)文章

  • Node.js學(xué)習(xí)之路14——Process進(jìn)程

    摘要:在中,只支持單線程。在這種場(chǎng)合下,如果能夠使用多進(jìn)程,則可以為每個(gè)請(qǐng)求分配一個(gè)進(jìn)程,從而可以更好地使用服務(wù)器端的資源。進(jìn)程進(jìn)程對(duì)象的屬性用于運(yùn)行應(yīng)用程序的可執(zhí)行文件的絕對(duì)路徑的版本號(hào)及其各依賴的版本號(hào)當(dāng)前運(yùn)行的平臺(tái)用于讀入標(biāo)準(zhǔn)輸入流的對(duì)象。 Process 在Node.js中,只支持單線程。但是在應(yīng)用程序中,如果只使用單線程進(jìn)行操作,從接收請(qǐng)求開始到返回響應(yīng)為止的這段時(shí)間內(nèi)可能存在很長(zhǎng)...

    darry 評(píng)論0 收藏0
  • Node.js學(xué)習(xí)之路08——fs文件系統(tǒng)之stream流的基本介紹

    摘要:中各種用于讀取數(shù)據(jù)的對(duì)象對(duì)象描述用于讀取文件代表客戶端請(qǐng)求或服務(wù)器端響應(yīng)代表一個(gè)端口對(duì)象用于創(chuàng)建子進(jìn)程的標(biāo)準(zhǔn)輸出流。如果子進(jìn)程和父進(jìn)程共享輸入輸出流,則子進(jìn)程的標(biāo)準(zhǔn)輸出流被廢棄用于創(chuàng)建子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤輸出流。 9. stream流 fs模塊中集中文件讀寫方法的區(qū)別 用途 使用異步方式 使用同步方式 將文件完整讀入緩存區(qū) readFile readFileSync 將文件部...

    BoYang 評(píng)論0 收藏0
  • Node.js中spawn與exec的異同比較

    摘要:返回值對(duì)象利用給定的命令以及參數(shù)執(zhí)行一個(gè)新的進(jìn)程,如果沒(méi)有參數(shù)數(shù)組,那么將默認(rèn)是一個(gè)空數(shù)組。當(dāng)子進(jìn)程執(zhí)行完畢后將會(huì)執(zhí)行的回調(diào)函數(shù),參數(shù)有返回值對(duì)象在中運(yùn)行一個(gè)命令,并緩存命令的輸出。 前言 眾所周知,Node.js在child_process模塊中提供了spawn和exec這兩個(gè)方法,用來(lái)開啟子進(jìn)程執(zhí)行指定程序。這兩個(gè)方法雖然目的一樣,但是既然Node.js為我們提供了兩個(gè)方法,那它...

    garfileo 評(píng)論0 收藏0
  • 深入理解Node.js 進(jìn)程與線程(8000長(zhǎng)文徹底搞懂)

    摘要:在單核系統(tǒng)之上我們采用單進(jìn)程單線程的模式來(lái)開發(fā)。由進(jìn)程來(lái)管理所有的子進(jìn)程,主進(jìn)程不負(fù)責(zé)具體的任務(wù)處理,主要工作是負(fù)責(zé)調(diào)度和管理。模塊與模塊總結(jié)無(wú)論是模塊還是模塊,為了解決實(shí)例單線程運(yùn)行,無(wú)法利用多核的問(wèn)題而出現(xiàn)的。 前言 進(jìn)程與線程是一個(gè)程序員的必知概念,面試經(jīng)常被問(wèn)及,但是一些文章內(nèi)容只是講講理論知識(shí),可能一些小伙伴并沒(méi)有真的理解,在實(shí)際開發(fā)中應(yīng)用也比較少。本篇文章除了介紹概念,通過(guò)...

    Harpsichord1207 評(píng)論0 收藏0
  • Node.js 全局對(duì)象 process

    摘要:是一個(gè)全局變量,對(duì)象的屬性。的源碼啟動(dòng)進(jìn)程,評(píng)估時(shí)返回函數(shù)失敗。調(diào)用監(jiān)聽器回調(diào)函數(shù)時(shí)會(huì)將的值作為唯一參數(shù)傳入。信號(hào)列表詳見標(biāo)準(zhǔn)的信號(hào)名,如等。返回一個(gè)對(duì)象,描述了進(jìn)程所用的內(nèi)存狀況,單位為字節(jié)。一旦當(dāng)前事件循環(huán)結(jié)束,調(diào)用回調(diào)函數(shù)。 process是一個(gè)全局變量,global對(duì)象的屬性。它的作用是描述當(dāng)前Node.js進(jìn)程狀態(tài)的對(duì)象,提供了一個(gè)與操作系統(tǒng)的簡(jiǎn)單接口。通常在你寫本地命令程序...

    JasonZhang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<