Node.js在child_process域和錯誤冒泡及捕獲實(shí)踐
child_process
child_進(jìn)程模塊提供派生子進(jìn)程的功能。它與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(`子進(jìn)程退出碼:$[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_進(jìn)程模塊還提供一些其他同步和異步可選功能。每個函數(shù)都是基于[child_process.spawn()]或[child_process.spawnSync()]實(shí)現(xiàn)的。
[child_process.exec()]:派生一個shell并在該shell上運(yùn)行命令。完成后,stdout和stderr將傳遞給回調(diào)函數(shù)。
const { spawn } = require('child_process');
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(`子進(jìn)程收到信號 ${signal} 而終止`);
});
// 發(fā)送 SIGHUP 到進(jìn)程
grep.kill('SIGHUP');
[child_process.execFile()]:類似于[child_procedure.exec()],但命令是直接派生的,而不首先派生shell。
[child_process.f分叉()]:派生一個新的NodeJs進(jìn)程,并通過建立IPC通信通道調(diào)用指定的模塊,這允許父進(jìn)程和子進(jìn)程相互發(fā)送信息。
[child_process.execSync()]:[child_procedure.exec()]的同步函數(shù)阻止節(jié)點(diǎn)J的事件循環(huán)。
[child_process.execFileSync()]:[child_cess.execFile()]的同步函數(shù)阻止節(jié)點(diǎn)J的事件循環(huán)。
options.detached
在Windows上,設(shè)置選項(xiàng)如果分離為true,則子進(jìn)程可以在父進(jìn)程退出后繼續(xù)運(yùn)行。子進(jìn)程有自己的控制臺窗口。一旦啟用了子進(jìn)程,就不能禁用它。
在非Windows平臺上,如果選項(xiàng)if detached設(shè)置為true,則子進(jìn)程將成為新進(jìn)程組和會話的領(lǐng)導(dǎo)者。請注意,子進(jìn)程可以在父進(jìn)程退出后繼續(xù)運(yùn)行,無論它們是否分離。
詳見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();
默認(rèn)情況下,父進(jìn)程將等待分離的子進(jìn)程退出。為了防止父進(jìn)程等待給定的子進(jìn)程,可以使用子進(jìn)程Unref()方法。這將導(dǎo)致父進(jìn)程的事件循環(huán)排除子進(jìn)程的引用計數(shù),使父進(jìn)程獨(dú)立于子進(jìn)程退出,除非在子進(jìn)程和父進(jìn)程之間建立了IPC通道。
使用分離選項(xiàng)啟動長時間運(yùn)行的進(jìn)程時,除非提供了未連接到父進(jìn)程的stdio配置,否則父進(jìn)程退出后,該進(jìn)程將不會在后臺繼續(xù)運(yùn)行。如果繼承了父進(jìn)程的stdio,則子進(jìn)程將保持與控制終端的連接。
例如,對于長時間運(yùn)行的進(jìn)程,為了忽略父進(jìn)程的終止,父進(jìn)程的stdio文件描述符被分離并忽略:
const { spawn } = require('child_process');
const subprocess = spawn(process.argv[0], ['child_program.js'], {
detached: true,
stdio: 'ignore'
});
subprocess.unref();
如果未傳遞信號,[ChildProcess]對象可能會觸發(fā)['error']事件。向已退出的子進(jìn)程發(fā)送信號不是錯誤,但可能會產(chǎn)生不可預(yù)測的后果。
特別是,如果一個進(jìn)程的PID被重新分配給另一個進(jìn)程,則該信號將被發(fā)送給該進(jìn)程,這可能會導(dǎo)致意外的結(jié)果。
注意,當(dāng)函數(shù)被稱為kill時,發(fā)送給子進(jìn)程的信號實(shí)際上可能不會終止該進(jìn)程。
'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 進(jìn)程
}, 2000);
一旦套接字被傳遞給子進(jìn)程,父進(jìn)程就無法再跟蹤套接字何時被銷毀。若要顯示此屬性,連接屬性將變?yōu)榭铡0l(fā)生這種情況時,不建議使用。
最大連接數(shù)。 建議子進(jìn)程中的任何消息處理程序都應(yīng)驗(yàn)證套接字是否存在,因?yàn)檫B接在發(fā)送到子進(jìn)程期間可能會關(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é)點(diǎn)。Js支持幾種機(jī)制來冒泡和處理應(yīng)用程序運(yùn)行時發(fā)生的錯誤。如何報告和處理這些錯誤完全取決于錯誤的類型和調(diào)用的API的樣式。 所有JavaScript錯誤都將被視為異常。將立即生成異常,并使用標(biāo)準(zhǔn)JavaScript拋出機(jī)制拋出錯誤。這些都是使用JavaScript語言提供的try/catch語句處理的。
try {
const m = 1;
const n = m + z;
} catch (err) {
// 在這里處理錯誤。
}
任何使用JavaScript的拋出機(jī)制都會導(dǎo)致異常。異常必須用try/catch處理,否則Node.js進(jìn)程將立即退出。 除了少數(shù)例外,同步API(任何不接受回調(diào)函數(shù)的阻塞方法,如[fs.readFileSync])將使用throw來報告錯誤。 異步API中的錯誤可以通過幾種方式報告: 大多數(shù)異步方法都接受回調(diào)函數(shù),該函數(shù)接受Error對象作為第一個參數(shù)。如果第一個參數(shù)不是null,而是一個Error實(shí)例,則表示發(fā)生了錯誤,應(yīng)進(jìn)行處理。
以上就是Node.js在child_process域和錯誤冒泡及捕獲實(shí)踐的詳細(xì)內(nèi)容,更多關(guān)于Node.js child_process錯誤捕獲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
手寫Node靜態(tài)資源服務(wù)器的實(shí)現(xiàn)方法
這篇文章主要介紹了手寫Node靜態(tài)資源服務(wù)器的實(shí)現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
Node.js npm命令運(yùn)行node.js腳本的方法
今天小編就為大家分享一篇Node.js npm命令運(yùn)行node.js腳本的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10
node.js中使用q.js實(shí)現(xiàn)api的promise化
這篇文章主要介紹了node.js中使用q.js實(shí)現(xiàn)api的promise化,promise一個標(biāo)準(zhǔn),它描述了異步調(diào)用的返回結(jié)果,包括正確返回結(jié)果和錯誤處理,需要的朋友可以參考下2014-09-09
詳解如何實(shí)現(xiàn)一個簡單的Node.js腳手架
本篇文章主要介紹了如何實(shí)現(xiàn)一個簡單的Node.js腳手架,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
Nodejs+express+ejs簡單使用實(shí)例代碼
本篇文章主要介紹了Nodejs+express+ejs簡單使用實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09

