With asynchronous I/O, there must be asynchronous programming! Learn asynchronous programming in Node.js today!

Introduction to Asynchronous Programming

Under the influence of synchronous I/O, CPU and I/O cannot overlap at the application level due to the slow I/O invocation. Synchronous I/O has been popular for many years to accommodate programmers’ reading habits.

But there are big performance issues!

Node uses JavaScript and its internal asynchrony library to take asynchrony directly to the business level. The biggest feature Node brings is the event-driven, non-blocking I/O model. Non-blocking I/O allows the CPU and I/O to be independent of each other, making better use of resources.

Asynchronous programming solutions

Purpose: Read the file contents corresponding to the main field in package.json

Callback

Asynchronous I/O operations are performed using callback functions

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);
  });
});
Copy the code

Question: How to solve callback hell?

Promise

Promise is a finite state machine with four states, including three core states: Pending, Fulfilled, Rejected and one state that has not started

Check out my previous post on Promise for more details

Using Promise, the implementation reads the file contents 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);
  });
Copy the code

In contrast to the previous solution with Callback, you can see that there are no nested callbacks and that asynchronous operations are handled by a series of chained calls.

The Callback to Promise

How do I convert a Callback to a Promise?

You can use Node’s built-in utility function util.promisify

You can do this yourself:

function promisify(fn, receiver) {
  return (. args) = > {
    return new Promise((resolve, reject) = > {
      fn.apply(receiver, [
        ...args,
        (err, res) = > {
          returnerr ? reject(err) : resolve(res); },]); }); }; }const readFilePromise = promisify(fs.readFile, fs);
Copy the code

await

Await functions catch exceptions using try catch (note parallelism)

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();
Copy the code

The syntax of await is written like synchronous programming, where the operations are serial and await execution line by line.

If several tasks can be done in parallel, this is not a good way to write. At this point, we can use promise.all to operate on parallel tasks

There will also be a small question, I asked the teacher after class, this is the teacher’s answer

Q: In the asynchronous part, speaking of serial and parallel, I have a question in the parallel part. If parallel scenario requires: whatever other mission success or failure, finish every asynchronous tasks to perform, finally unified handling errors, then in use Promise. All to handle multiple asynchronous task, hit the first mission will return error, how to operate to make all task completes, unified handling errors again

All handles multiple requests. When all requests are successful, resolve returns an array containing the result of the execution. If a request fails, reject the error immediately, so we can’t implement this with promise.all. Promise has an allSettled method, developer.mozilla.org/en-US/docs/…

Event

Publish subscribe mode, Node.js built-in Events module

For example, HTTP Server on(‘ Request ‘) event listener

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);
Copy the code

reference

  • Bytedance Youth Training PPT + video
  • Node.js