If there is asynchronous I/O, there must be asynchronous programming! Let’s learn asynchronous programming in Node.js today!
The former single-threaded model was under the influence of synchronous I/O due to slow I/O calls. , causing the CPU and I/O to be unable to overlap at the application level. In order to take care of the reading and thinking habits of programmers, synchronous I/O has been popular for many years. [Recommended learning: "nodejs Tutorial"]
But there are big performance problems!
Node uses JavaScript and its internal asynchronous library to directly upgrade asynchronous to the business level. The biggest feature brought by Node is the event-driven non-blocking I/O model. Non-blocking I/O can prevent the CPU and I/O from waiting on each other, allowing resources to be better utilized.
Purpose: Read the file content corresponding to the main field in package.json
Callback
Using callback functions for asynchronous I/O operations
const fs = require("fs"); fs.readFile("./package.json", { encoding: "utf-8" }, (err, data) => { if (err) throw err; const { main } = JSON.parse(data); fs.readFile(main, { encoding: "utf-8" }, (err, data) => { if (err) throw err; console.log(data); }); });
Problem: How to solve Callback hell?
Promise
Promise is a finite state machine with four states, three of which are Pending and Fulfilled. ( Completed), Rejected (rejected), and there is also an unstarted state
For details, please see my previous blog postInitial exploration of Promise
Use Promise to read the file content corresponding to the main field in package.json
const { readFile } = require("fs/promises"); readFile("./package.json", { encoding: "utf-8" }) .then((res) => { return JSON.parse(res); }) .then((data) => { return readFile(data.main, { encoding: "utf-8" }); }) .then((res) => { console.log(res); });
Compared with the previous solution using Callback, it can be seen that there are no nested callbacks, through a series of chain calls to handle asynchronous operations.
Callback to Promise
How to convert Callback to Promise form?
You can use Node’s own tool function util.promisify
You can implement it yourself:
function promisify(fn, receiver) { return (...args) => { return new Promise((resolve, reject) => { fn.apply(receiver, [ ...args, (err, res) => { return err ? reject(err) : resolve(res); }, ]); }); }; } const readFilePromise = promisify(fs.readFile, fs);
await
await function uses try catch to catch exceptions (pay attention to parallel processing)
const { readFile } = require("fs/promises"); const start = async () => { const { main } = JSON.parse( await readFile("./package.json", { encoding: "utf-8" }) ); const data = await readFile(main, { encoding: "utf-8" }); console.log(data); }; start();
The syntax of await is written like synchronous programming. The operation here is a serial operation, which will be one line One line is waiting to be executed.
If several tasks can be paralleled, it would not be good to write like this. This is, we can use Promise.all to operate parallel tasks
There will also be a small question here. I asked the teacher after class, and this is the teacher’s answer
[Q] Regarding asynchronous processing, when it comes to serialization and parallelism, I have a question about parallel processing. If the parallel scenario requires that each asynchronous task must be executed regardless of the success or failure of other tasks, and finally the error will be handled uniformly, then when using Promise.all to process multiple asynchronous tasks, the first task execution error will be encountered. will be returned. How can we complete all tasks and handle errors uniformly?
[Answer] Promise.all handles multiple requests. When all requests are successful, resolve returns an array. , which contains the execution results. If a request fails, the error will be rejected immediately, so we cannot use Promise.all to implement this. Promise has an allSettled method, developer.mozilla.org/en-US/docs/…
##Event
Publish and subscribe mode, Node.js built-in events modulesuch as HTTPserver on('request') event monitoring
const EventEmitter = require("events"); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on("event", () => { console.log("an event occurred!"); }); myEmitter.emit("event"); const http = require("http"); const server = http.createServer((req, res) => { res.end("hello!!! this is YK!!!"); }); server.on("request", (req, res) => { console.log(req.url); }); server.listen(3000);
Original address: https://juejin.cn/post/7005509871000895524Author: YK bacteria
For more programming related knowledge, please visit: Programming Video! !
The above is the detailed content of Learn more about asynchronous programming in Node.js and share four solutions. For more information, please follow other related articles on the PHP Chinese website!