Node.js在child_process域和錯誤冒泡及捕獲實踐
child_process
child_進程模塊提供派生子進程的功能。它與popen(3)相似但不相同。此函數(shù)主要由[child_process.spown()]函數(shù)提供:
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`輸出:${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`錯誤:${data}`);
});
ls.on('close', (code) => {
console.log(`子進程退出碼:$[code]`);
});
const { exec } = require('child_process');
exec('my.bat', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
// 文件名帶有空格的腳本:
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
// 或:
exec('"my script.cmd" a b', (err, stdout, stderr) => {
// ...
});
child_進程模塊還提供一些其他同步和異步可選功能。每個函數(shù)都是基于[child_process.spawn()]或[child_process.spawnSync()]實現(xiàn)的。
[child_process.exec()]:派生一個shell并在該shell上運行命令。完成后,stdout和stderr將傳遞給回調(diào)函數(shù)。
const { spawn } = require('child_process');
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(`子進程收到信號 ${signal} 而終止`);
});
// 發(fā)送 SIGHUP 到進程
grep.kill('SIGHUP');
[child_process.execFile()]:類似于[child_procedure.exec()],但命令是直接派生的,而不首先派生shell。
[child_process.f分叉()]:派生一個新的NodeJs進程,并通過建立IPC通信通道調(diào)用指定的模塊,這允許父進程和子進程相互發(fā)送信息。
[child_process.execSync()]:[child_procedure.exec()]的同步函數(shù)阻止節(jié)點J的事件循環(huán)。
[child_process.execFileSync()]:[child_cess.execFile()]的同步函數(shù)阻止節(jié)點J的事件循環(huán)。
options.detached
在Windows上,設(shè)置選項如果分離為true,則子進程可以在父進程退出后繼續(xù)運行。子進程有自己的控制臺窗口。一旦啟用了子進程,就不能禁用它。
在非Windows平臺上,如果選項if detached設(shè)置為true,則子進程將成為新進程組和會話的領(lǐng)導(dǎo)者。請注意,子進程可以在父進程退出后繼續(xù)運行,無論它們是否分離。
詳見setsid(2)。
const fs = require('fs');
const { spawn } = require('child_process');
const out = fs.openSync('./out.log', 'a');
const err = fs.openSync('./out.log', 'a');
const subprocess = spawn('prg', [], {
detached: true,
stdio: [ 'ignore', out, err ]
});
subprocess.unref();
默認情況下,父進程將等待分離的子進程退出。為了防止父進程等待給定的子進程,可以使用子進程Unref()方法。這將導(dǎo)致父進程的事件循環(huán)排除子進程的引用計數(shù),使父進程獨立于子進程退出,除非在子進程和父進程之間建立了IPC通道。
使用分離選項啟動長時間運行的進程時,除非提供了未連接到父進程的stdio配置,否則父進程退出后,該進程將不會在后臺繼續(xù)運行。如果繼承了父進程的stdio,則子進程將保持與控制終端的連接。
例如,對于長時間運行的進程,為了忽略父進程的終止,父進程的stdio文件描述符被分離并忽略:
const { spawn } = require('child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore'
});
subprocess.unref();
如果未傳遞信號,[ChildProcess]對象可能會觸發(fā)['error']事件。向已退出的子進程發(fā)送信號不是錯誤,但可能會產(chǎn)生不可預(yù)測的后果。
特別是,如果一個進程的PID被重新分配給另一個進程,則該信號將被發(fā)送給該進程,這可能會導(dǎo)致意外的結(jié)果。
注意,當(dāng)函數(shù)被稱為kill時,發(fā)送給子進程的信號實際上可能不會終止該進程。
'use strict';
const { spawn } = require('child_process');
const subprocess = spawn(
'sh',
[
'-c',
`node -e "setInterval(() => {
console.log(process.pid, 'is alive')
}, 500);"`
], {
stdio: ['inherit', 'inherit', 'inherit']
}
);
setTimeout(() => {
subprocess.kill(); // 不會終止 shell 中的 node 進程
}, 2000);
一旦套接字被傳遞給子進程,父進程就無法再跟蹤套接字何時被銷毀。若要顯示此屬性,連接屬性將變?yōu)榭铡0l(fā)生這種情況時,不建議使用。
最大連接數(shù)。 建議子進程中的任何消息處理程序都應(yīng)驗證套接字是否存在,因為連接在發(fā)送到子進程期間可能會關(guān)閉。
cipher.update
用數(shù)據(jù)更新密碼。如果給定inputEncoding參數(shù),其值必須為“utf8”、“ascii”或“latin1”,并且數(shù)據(jù)參數(shù)是使用指定編碼的字符串。如果未給定inputEncoding參數(shù),則數(shù)據(jù)必須為Buffer、TypedArray或DataView。如果數(shù)據(jù)是Buffer、TypedArray或DataView,則忽略inputEncoding。
OutputEncoding指定加密數(shù)據(jù)的輸出格式,可以是“latin1”、“base64”或“hex”。如果指定了outputEncoding,則返回具有指定編碼的字符串。如果未提供outputEncoding,將返回Buffer。 密碼。
update()方法可以用新數(shù)據(jù)多次調(diào)用,直到調(diào)用密碼Final()。
['cipher.final()'][]調(diào)用密碼。update()。
final()將拋出錯誤。
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
let decrypted = '';
decipher.on('readable', () => {
const data = decipher.read();
if (data)
decrypted += data.toString('utf8');
});
decipher.on('end', () => {
console.log(decrypted);
// Prints: some clear text data
});
const encrypted =
'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
decipher.write(encrypted, 'hex');
decipher.end();
const crypto = require('crypto');
const fs = require('fs');
const decipher = crypto.createDecipher('aes192', 'a password');
const input = fs.createReadStream('test.enc');
const output = fs.createWriteStream('test.js');
input.pipe(decipher).pipe(output);
返回所有剩余的解密內(nèi)容。如果outputEncoding參數(shù)是“latin1”、“ascii”或“utf8”之一,則返回字符串。如果未提供輸出編碼,則返回Buffer。
一旦解密了final()方法,decipher對象就不能再用于解密數(shù)據(jù)。正在嘗試調(diào)用解密。final()多次導(dǎo)致拋出錯誤。
const crypto = require('crypto');
const assert = require('assert');
// Generate Alice's keys...
const alice = crypto.createDiffieHellman(2048);
const aliceKey = alice.generateKeys();
// Generate Bob's keys...
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();
// Exchange and generate the secret...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);
// OK
assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
錯誤的冒泡和捕獲
節(jié)點。Js支持幾種機制來冒泡和處理應(yīng)用程序運行時發(fā)生的錯誤。如何報告和處理這些錯誤完全取決于錯誤的類型和調(diào)用的API的樣式。 所有JavaScript錯誤都將被視為異常。將立即生成異常,并使用標(biāo)準(zhǔn)JavaScript拋出機制拋出錯誤。這些都是使用JavaScript語言提供的try/catch語句處理的。
try {
const m = 1;
const n = m + z;
} catch (err) {
// 在這里處理錯誤。
}
任何使用JavaScript的拋出機制都會導(dǎo)致異常。異常必須用try/catch處理,否則Node.js進程將立即退出。 除了少數(shù)例外,同步API(任何不接受回調(diào)函數(shù)的阻塞方法,如[fs.readFileSync])將使用throw來報告錯誤。 異步API中的錯誤可以通過幾種方式報告: 大多數(shù)異步方法都接受回調(diào)函數(shù),該函數(shù)接受Error對象作為第一個參數(shù)。如果第一個參數(shù)不是null,而是一個Error實例,則表示發(fā)生了錯誤,應(yīng)進行處理。
以上就是Node.js在child_process域和錯誤冒泡及捕獲實踐的詳細內(nèi)容,更多關(guān)于Node.js child_process錯誤捕獲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Restify中接入Socket.io報Error:Can’t set headers的錯誤解決
這篇文章主要給大家介紹了在Restify中接入Socket.io報Error:Can’t set headers的錯誤解決方法,文中介紹的非常詳細,對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-03-03
Node.js中的package.json與cnpm命令行工具介紹
這篇文章介紹了Node.js中的package.json與cnpm命令行工具,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06
基于promise.js實現(xiàn)nodejs的promises庫
promise是JavaScript實現(xiàn)優(yōu)雅編程的一個非常不錯的輕量級框架。該框架可以讓你從雜亂的多重異步回調(diào)代碼中解脫出來,并把精力集中到你的業(yè)務(wù)邏輯上。2014-07-07
快速刪除 node_modules 目錄的集中方法(多種方法)
本文介紹了三種快速刪除node_modules目錄的方法:使用rimraf工具、通過npx運行rimraf以及在Windows命令提示符中使用del命令,每種方法都適合不同的操作系統(tǒng)和使用場景2024-11-11
windows8.1+iis8.5下安裝node.js開發(fā)環(huán)境
這篇文章主要介紹了windows8.1+iis8.5下安裝node.js開發(fā)環(huán)境的方法,需要的朋友可以參考下2014-12-12
nodejs發(fā)布靜態(tài)https服務(wù)器的方法
這篇文章主要介紹了nodejs發(fā)布靜態(tài)https服務(wù)器的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
nodejs獲取微信小程序帶參數(shù)二維碼實現(xiàn)代碼
這篇文章主要介紹了nodejs獲取微信小程序帶參數(shù)二維碼實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04

