ES6 modularization
1. Review node How to realize modularization in JS
node.js follows the modular specification of CommonJS. Of which:
- Import other modules using the require () method
- Module is used by external sharing members of the module Exports object
Benefits of modularity:
We all follow the same modular specification to write code, which reduces the cost of communication and greatly facilitates the mutual call between various modules for the benefit of others and ourselves
2. Classification of front-end modular specifications
Before the birth of ES6 modular specification, there were other modular specifications such as AMD, CMD and CommonJS. But these are not official, there are still some differences and limitations
For example:
AMD and CMD are suitable for browser side JavaScript modularization
CommonJS is suitable for server-side JavaScript modularization
In order to reduce the learning difficulty and development cost, the unified ES6 modularization was born!
3. What is the ES6 modular specification
Defined in ES6 modular specification:
- Each JS file is an independent module
- To import a module, use the import keyword
- Use the export keyword for the outward shared module
4. Basic syntax of ES6 modularization
It mainly includes the following three uses
- Default export and default import
- On demand export and on demand import
- Directly import and execute the code in the module
4.1 default export
Syntax: export default is the default exported member
let n1 = 10 let n2 = 20 function show () {} // Share objects outward export default { n1, show }
4.2 default import
Syntax: import receive name from 'module identifier'
import m1 from './1. Default export' console.log(m1);
You can only get n1 and show
4.3 export on demand and import on demand
On demand export syntax: emport members exported on demand
export let s1 = 'aaa' export let s2 = 'ccc' export function say() { }
On demand import syntax: import {S1} from 'module identifier'
import { s1, s2, say } from "./3.Export on demand";
Promise
1. Callback hell
The nesting of multi-layer callback functions forms a callback hell.
setTimeout(() => { // first floor console.log('Output after one second delay'); setTimeout(() => { //The second floor console.log('Output with another two seconds delay'); setTimeout(() => { //Third floor console.log('Delay another three seconds'); }, 3000) }, 2000) }, 1000);
Disadvantages: the code is highly coupled, which affects the whole body and is difficult to maintain
In order to solve this problem, the concept of Promise is proposed
1.1 basic concept of promise
① Promise is a constructor
- We can create an instance of Promise const p = new Promise()
- The Promise instance object from new represents an asynchronous operation
② Promise. The prototype contains a then() method
③ . The then() method is used to predetermine success and failure callback functions
- p. Then (successful callback function, failed callback function)
- p.then( result => { } , error => { } )
- The successful callback function is required, and the failed callback function is optional
1.2 then FS asynchronous reading of file contents
Call the readFile() method provided by then-f to asynchronously read the contents of the file, and its return value is the Promise instance object.
So you can call The then() method formulates the callback function after success and failure for each Promise asynchronous operation.
import thenFs from 'then-fs' // thenFs. Readfile ('. / files / 1. TXT','utf8 ') will get its Promise object thenFs.readFile('./files/1.txt', 'utf8').then((r1) => { console.log(r1) }) thenFs.readFile('./files/2.txt', 'utf8').then((r2) => { console.log(r2) }) thenFs.readFile('./files/3.txt', 'utf8').then((r3) => { console.log(r3) }) // At present, we only read data asynchronously, and the order cannot be guaranteed
- Optimization:
import thenFs from 'then-fs' // thenFs. Readfile ('. / files / 1. TXT','utf8 ') will get its Promise object thenFs.readFile('./files/1.txt', 'utf8') .then((r1) => { console.log(r1); return thenFs.readFile('./files/2.txt', 'utf8') }) .then((r2) => { console.log(r2); return thenFs.readFile('./files/3.txt', 'utf8') }) .then((r3) => { console.log(r3); })
2. Adoption Catch catch error
If an error occurs in Promise's chain operation, Promise. Com can be used prototype. Catch method for capture and processing
import thenFs from 'then-fs' // thenFs. Readfile ('. / files / 1. TXT','utf8 ') will get its Promise object thenFs.readFile('./files/11.txt', 'utf8') // No 11 Txt file .then((r1) => { console.log(r1); return thenFs.readFile('./files/2.txt', 'utf8') }) .then((r2) => { console.log(r2); return thenFs.readFile('./files/3.txt', 'utf8') }) .then((r3) => { console.log(r3); }) .catch((err) => { console.log(err.message); }) // Error: ENOENT: No such file
3. Promise.all() method
Promise. The all () method will initiate parallel promise asynchronous operations, and will not execute the next step until all asynchronous operations are completed then operation (waiting mechanism)
import thenFs from "then-fs"; const promiseArr = [ thenFs.readFile('./files/1.txt', 'utf8'), thenFs.readFile('./files/2.txt', 'utf8'), thenFs.readFile('./files/3.txt', 'utf8') ] Promise.all(promiseArr).then(result => { console.log(result); }) //['111','222','333']
4. Promise.race() method
As soon as any asynchronous operation is completed, the next step is executed immediately then operation (racing mechanism)
import thenFs from "then-fs"; const promiseArr = [ thenFs.readFile('./files/1.txt', 'utf8'), thenFs.readFile('./files/2.txt', 'utf8'), thenFs.readFile('./files/3.txt', 'utf8') ] Promise.race(promiseArr).then(result => { console.log(result); }) // 333
5. Method of encapsulating and reading files
Requirements for method encapsulation:
- ① The name of the method is defined as getFile
- ② Method receives a formal parameter fpath that identifies the path of the file to be read
- ③ The return value of the method is Promise instance object
5.1 basic definition of GetFile method
import fs from 'fs' function getFile(fpath) { // If the getFile function is called, a Promise object is returned return new Promise(function (resolve, reject) { fs.readFile(fpath, 'utf8', (err, dataStr) => { // If an error occurs, pass err into the reject object if (err) return reject(err) // If the previous sentence fails to execute the description, pass the dataStr to resolve resolve(dataStr) }) }) } getFile('./files/1.txt').then((r1) => { console.log(r1) }, (err) => { console.log(err.message); })
async / await
1. What is async / await
async / await is a new syntax introduced by ES8 to simplify Promise asynchronous operations. Before that, developers could only use the chain The method of then() handles Promise asynchronous operations
2. Basic use of async / await
import thenFs from 'then-fs' async function getAllFile() { const r1 = await thenFs.readFile('../files/1.txt', 'utf8'); console.log(r1); // 111 } getAllFile();
3. async / await considerations
In the async method, the code before the first await will be executed synchronously, and the code after await will be executed asynchronously
// Here A is synchronous execution console.log('A'); async function getAllFile() { console.log('B'); // Until now, it is synchronous execution. Next, we encounter the first await, so we exit the main thread and enter line 12. The following are asynchronous execution const r1 = await thenFs.readFile('../files/1.txt', 'utf8'); const r2 = await thenFs.readFile('../files/2.txt', 'utf8'); const r3 = await thenFs.readFile('../files/3.txt', 'utf8'); console.log(r1, r2, r3); console.log('D'); } getAllFile(); console.log('C');
Macro and micro tasks
1. What are macro tasks and micro tasks
JavaScript divides asynchronous tasks into two categories:
① Macro task
- Asynchronous AJAX request
- setTimeout,setInterval
- File operation
- Other macro tasks
② Micro task
- promise.then, . catch and finally
- process.nextTick
- Other micro tasks
2. Execution sequence of macro task and micro task
Macro task completion - > judge micro task? - > Execute all micro tasks - > next macro task
API interface cases
1. Case requirements
Based on MySQL database + Express, it provides API interface service for external user list. The technologies used are as follows:
- Third party packages express and mysql2
- ES6 modularization
- Promise
- async / await
2. Main implementation steps
① Build the basic structure of the project
② Create basic server
③ Create db database operation module
④ Create user_ctrl service module
⑤ Create user_router routing module
3. Build the basic structure of the project
① Enable ES6 modular support
- In package JSON declares "type": "module"
② Installing third-party dependency packages
- Run NPM install express@4.17.1 mysql2@2.2.5
4. Create a basic server
import express from 'express' const app = express() // Enable the server and start on port 80 app.listen(80, () => { console.log('server running at http://127.0.0.1'); })
5. Create db database operation module
Newly created folder db
import mysql from 'mysql2' // mysql. The return value of createpool () is a database connection object const pool = mysql.createPool({ host: '127.0.0.1', // Specify which computer to operate the database on port: 3306, // Specify the port number of the database to connect to database: 'my_db_01', // Specify which database to operate on user: 'root', // Account to log in to the database password: 'admin123' // password }); // Export the pool for external use export default pool.promise();
6. Create user_ctrl module
import db from '../db/index.js' // Using ES6 on demand export syntax export async function getAllUser(req, res) { const [rows] = await db.query('select id, username, nickname from ev_users') res.send({ status: 0, message: 'User list data obtained successfully!', data: rows, }) } getAllUser()
7. Create user_router module
import express from 'express' import { getAllUser } from '../2.controller/user_ctrl.js' // 1. Create routing object const router = new express.Router(); // 3. Mount a routing rule // router.get listens to GET requests from clients // As long as the user is a GET request and requests the address / user, the request is handed over to the getAlluser function for processing router.get('/user', getAllUser) // 2. Share routing objects export default router // 4. Next, go back to app JS file
app.js:
import express from 'express' import userRouter from './3.router/user_router.js' const app = express() // Add: 1 Call app Use ('') to mount // If the user accesses in / api mode, the routing module userRouter is specified app.use('/api', userRouter) // Enable the server and start on port 80 app.listen(80, () => { console.log('server running at http://127.0.0.1'); })
target
- Be able to know how to use the modular syntax of ES6
- Can you know how to use Promise to solve the problem of callback hell
- Know how to use async / await to simplify Promise calls
- Be able to say what EventLoop is
- Be able to tell the execution order of macro tasks and micro tasks