import * as file_system from 'fs'; import * as path from 'path'; const Blocking = () => { // Blocks here until 'Data.txt' file is read: const data: Buffer = file_system.readFileSync(path.resolve(__dirname, '..') + "/Data.txt"); console.log(data.toLocaleString()); // 'Data' is displayed... console.info("This text appears *AFTER* 'Data'"); } export default Blocking;
import * as file_system from 'fs'; import * as path from 'path'; const Non_blocking = () => { file_system.readFile((path.resolve(__dirname, '..') + "/Data.txt"), (error, data) => { if (error) throw error; console.log(data.toLocaleString()); // 'Data' is displayed... }); console.info("This text appears *BEFORE* 'Data'"); } export default Non_blocking;
Main
programimport Blocking from './Blocking'; import Non_blocking from './Non_blocking'; (function Main() { console.clear(); console.info("Executable file: " + __filename + "\n"); Blocking(); setTimeout((duration) => { console.info(duration + " elapsed..."); Non_blocking(); }, 2500, '2.5 sec.'); })();
Exercise
- Process two images in parallel with Sharp image processing library here…
Predefined event types identified by names like
'close'
,'error'
,'finish'
… are available from (typed) resources like standard input, standard output….(function Keyboard(information) { console.info(`${information}`); const output_stream = fs.createWriteStream( path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') + "/Keyboard.txt"); output_stream.on('error', (error) => console.info(`error: ${error.message}`)); const input_stream = readline.createInterface({ // 'import readline from 'node:readline';' input: process.stdin, output: process.stdout, prompt: "Enter a sentence: " }); input_stream.prompt(); input_stream.on('line', (line) => { switch (line.trim()) { case 'exit': input_stream.close(); break; default: output_stream.write(line + '\n'); input_stream.prompt(); // Next sentence... } }).on('close', () => { output_stream.end(); output_stream.on('finish', () => console.info("Sentences have been written to 'Keyboard.txt'...")); // Program stop (without error) is queued: setTimeout(() => process.exit(0)); }); })("'Keyboard' app. started...");
Node.js offers a native event model, which in particular allows custom event emission and reception. An advanced event model is based on the RxJS library.
Event reception
// import {channel} from "./Input"; // Compilation... import {channel} from "./Input.js"; // Execution... channel.on('html', (html) => console.info("***\n" + html));
Event emission
import events from "node:events"; import fs from "node:fs"; import path from "node:path"; import {fileURLToPath} from "node:url"; export const channel = new events.EventEmitter(); (function Input(information) { console.info(`${information}`); const __dirname = path.dirname(fileURLToPath(import.meta.url)); const input_stream: fs.ReadStream = fs.createReadStream(path.resolve(__dirname, '..') + "/index.html", 'utf8'); input_stream.on('error', (error) => console.info(`error: ${error.message}`)); input_stream.on('data', (html) => channel.emit('html', html)); })("'Events' app. started...");
export default class OpenSLR_org_88 { // https://gitlab.com/nicolasobin/att-hack … private static _Audio_file_processing(datum: any, audio_file_name: string): never | void { const audio_stream = file_system.createReadStream(OpenSLR_org_88.Path + audio_file_name); let audio = new Uint8Array; audio_stream.on('error', (error) => { throw new Error("Audio file extraction failed... " + error); }); audio_stream.on('end', () => { datum.audio = audio; // File destruction? // file_system.unlink(OpenSLR_org_88.Path + audio_file_name, (error) => { // if (error) // console.error(OpenSLR_org_88.Path + audio_file_name + " audio file destruction failed... " + error); // }); }); audio_stream.on('data', (chunk) => { // console.assert(chunk instanceof Uint8Array && chunk.constructor.name === 'Buffer'); // console.info(`Chunk of size ${chunk.length}... with raw data: ${chunk}`); // console.assert(audio.byteLength === audio.length); const _audio = new Uint8Array(audio.byteLength + chunk.length); _audio.set(audio); // Copy... _audio.set(chunk as Uint8Array, audio.byteLength); // Add... audio = _audio; // Update... }); } … }