摘要:在行中,我們將子進(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子進(jìn)程的實(shí)現(xiàn){ 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); }); }); }
以下代碼用 @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.stdin 和 process.stderr,如前面所述。
在B行中不會(huì) await 寫完成。而是 await 子進(jìn)程 sink 完成。
接下來(lái)了解 streamWrite() 的工作原理。
寫流操作的 promiseNode.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è) await,DONE 將會(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
摘要:在中,只支持單線程。在這種場(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)...
摘要:中各種用于讀取數(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 將文件部...
摘要:返回值對(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è)方法,那它...
摘要:在單核系統(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ò)...
摘要:是一個(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)單接口。通常在你寫本地命令程序...
閱讀 810·2021-10-14 09:43
閱讀 2133·2021-09-30 09:48
閱讀 3457·2021-09-08 09:45
閱讀 1104·2021-09-02 15:41
閱讀 1900·2021-08-26 14:15
閱讀 787·2021-08-03 14:04
閱讀 2986·2019-08-30 15:56
閱讀 3082·2019-08-30 15:52