1. callback function
-
A means of encapsulating code
-
What is the concept of callback
=>Pass function A as an argument to function B
=>Call function A as A formal parameter inside function B
=>We call this behavior a callback function
=>We say that function A is the callback function of function B
function A() { console.log('I am A function') } function B(fn) { // At this time, fn parameter accepts the content inside () when written in B(): A // At this time, fn parameter accepts the address of global function A // At this time, fn parameter and global variable A operate on A function space console.log('I am B function') // Calling fn is actually calling and executing the global A function fn() } // Call B function // A is the address of a save function // The address of function A is passed as an argument to the fn parameter inside function B B(A) // Function A is the callback function of function B
-
Why do I need a callback function
-
If the code is synchronized from beginning to end, no callback function is required
=>When you're encapsulating code
=>And there are asynchronous times in the code
=>And you need to do something at the end of asynchrony
=>Using callback
Explanation: why do asynchronous end encapsulation use callback
-
Because JS is a single thread, you can only do one thing at a time
-
Main: the end time of asynchrony is uncertain
-
Example: takeout
=>A takeout can only do one thing at a time
=>If you want to bring an extra pair of chopsticks
=>Scheme 1: call the takeout when he just arrives at the store
=>Option 2: give a note when ordering
-
Callback hell
-
When callbacks are nested callbacks, the code reading and maintainability are not high
Solve the problem of callback Hell:
-
Promise to solve the callback hell
-
analysis:
=>Promise is to solve the callback hell
=>Callback hell is because callback functions are nested too much
=>Callback function, in order to solve the encapsulation of doing something at the end of asynchrony
=>Promise is an elegant scheme for asynchronous code encapsulation
// Why do I need a callback function // Encapsulate a piece of code // Example: what the takeout company does well function waimai(beizhu) { // Get a random integer from 1000 to 6000 const time = 1000 * Math.round(Math.random() * 5 + 1) console.log(' on the way ' + time) // We use setTimeout to simulate a network environment request setTimeout(() => { console.log('Arrived at the store, Get the takeout') // Put the code I need to execute directly in this position // Then this encapsulation is meaningless // You need to use the callback function // Because this position is the end of asynchrony // Calling beizhu from this location is called at the end of asynchrony // No matter when you arrive at the store // After you get the takeout, carry out the notes beizhu() }, time) } // User needs: want to take an extra pair of chopsticks waimai(function () { console.log('Take an extra pair of chopsticks') }) // User needs: want to get more pepper waimai(function () { console.log('Get more pepper') })
2. Callback hell
understand
-
A situation when using callback function to encapsulate code
-
Callback functions are nested inside
-
When you use a lot of code encapsulated by callback functions, there will be structural disorder
=>It is not conducive to code reading and maintenance
-
To solve the callback hell
=>A new syntax called Promise appears in the syntax of ES6
=>To turn asynchronous code encapsulation into Promise syntax encapsulation
=>Callbacks are no longer used to encapsulate asynchronous code
=>Essence: used to encapsulate asynchronous code
Implementation requirements:
-
Send a request, request an interface
=>Wait until the response comes back
=>Print content on console
-
Send the second request and request the second interface
=>The request must be sent again after the first request and after printing
=>Print the response on the console
-
Send the third request and request the third interface
=>It is required to send the request again after the second request and after printing
=>Print the response on the console
<script src="jquery.min.js"></script> // Realize requirement 1: $.ajax({ url: 'http://localhost:8888/test/first', success: function (res) { console.log('Results of the first request') console.log(res) // When the code in this position is executed, it must be the end of the first request // Demand 2: $.ajax({ url: 'http://localhost:8888/test/second', dataType: 'json', success: function (res) { console.log('Result of the second request') console.log(res) // When the code in this position is executed, it must be the end of the second request // Demand 3: $.ajax({ url: 'http://localhost:8888/test/third', data: 'name=Jack&age=18', dataType: 'json', success: function (res) { console.log('Results of the third request') console.log(res) } }) } }) } })
ajax here uses jquery
3. Know Promise
-
Is a syntax that appears in ES6
-
Promise is also a JS built-in constructor
-
promise - commitment:
- How many committed states are there?
=>Continue (during continuous execution)
=>Success
=>Fail - Conversion between commitment states: can only be converted once
=>Or continue to convert to success
=>Or continue to convert to failure
- How many committed states are there?
-
Promise also has three states
=>Continue: pending
=>Success: fulfilled
=>Failed: rejected
const p = new Promise(function (resolve, reject) { // ... // ... }) // Register a successful function for the current commitment p.then(function () { }) // Register a failed function for the current commitment p.catch(function () { })
How to change promise status
- In the a function of new Promise
- Two parameters are acceptable
1. The first parameter: you can convert the Promise status from continue to success
2. Second parameter: the Promise status can be changed from continue to fail
// 1. Asynchronous code const p = new Promise(function (resolve, reject) { // resolve is a successful conversion method // When you write resolve(), you are converting the promise state to success // Will execute the b function written in. then // reject is a method of converting to failure // When you write reject(), you are converting the state of the promise to failure // It will execute the c function written in. catch // These two can only write one // Write asynchronous code that you need to encapsulate const time = 1000 * Math.round(Math.random() * 5 + 1) console.log('Promise to be together all your life') setTimeout(() => { if (time >= 3000) { // resolve() calls the function b inside then // So the time content written inside () here is the argument to b in then resolve(time) } else { // reject() calls the catch internal function c // Therefore, the time content written in () here is the argument to c in catch, and it is also an error message reject(time) } }, time) }) // Two methods called by promise object // Registration succeeded p.then(function b(t) { // Function b will not be called directly // The code in this position will be called and executed when p the promise state changes from continue to success console.log(t, 'Successful function b') // t is the content of time in the resolve parentheses written inside promise }) // Registration failed p.catch(function c(err) { // Function c is not called directly // The code in this position will be called and executed when p the promise state changes from continue to fail console.log(err, 'Failed function c') })
4. Advanced syntax of promise
-
When a Promise is then within the code
-
As long as you return a new promise object inside the previous then with return
-
Then of the new promise object can continue writing then directly after the previous then
Requirements:
-
Send a request for the first interface
-
Send the second request and request the second interface
=>Premise: you must wait until the end of the first request to send it again
function myPromiseAjax(options = {}) { const p = new Promise((resolve, reject) => { // Execute ajax $.ajax({ url: options.url, data: options.data, type:options.type, dataType: options.dataType, success: function (res) { resolve(res) } }) }) // Return my promise object return p }
myPromiseAjax({ url: 'http://localhost:8888/test/first' }) .then(res => { console.log('The first request is over') console.log(res) // return a new promise object return myPromiseAjax({ url: 'http://localhost:8888/test/second', dataType: 'json' }) }) .then(res => { console.log('Second request result') console.log(res) // return a new promise object return myPromiseAjax({ url: 'http://localhost:8888/test/third', data: 'name=Jack&age=20', dataType: 'json' }) }) .then(res => { console.log('Results of the third request') console.log(res) })
5. async function and await keyword
-
Syntax between ES7 and es8
-
effect:
-
In order to solve the Promise problem, write the Promise code more gracefully
-
Core function: write asynchronous code to look like synchronous code, but the essence is asynchronous
Syntax:
=>Async keyword (asynchronous)
- Use: write in front of the function
(it can be a declarative function, a function expression, or an arrow function)
// async syntax async function fn() {} const fn = async function () {} const fn = async a => {}
effect:
-
The await keyword can be used in this function
-
It will turn this function into an asynchronous function, just called an asynchronous function
(this asynchronous function is not our real asynchronous code, but gives this function a name)
=>It affects the code inside the function and does not affect the code outside the function
await keyword (wait)
- requirement:
-
await must be written inside an asynchronous function with async keyword
-
What await waits for must be a promise object, otherwise it can't wait
-
effect:
=>The results in promise that should have been accepted by the code in then,
Variable acceptance can be defined directly in front of await
=>Subsequent code will not be executed until promise is executed
console.log('start') // ① start async function fn() { console.log('I am fn Code inside the function') // ② // Because pAjax is code encapsulated according to the syntax form of promise // pAjax returns a promise object // fn function, when the code of pAjax is executed // Will wait until the asynchronous code is completely executed and the result is assigned to r1 // Continue to execute the following code const r1 = await pAjax({ url: 'http://localhost:8888/test/first' }) console.log(r1) // ④ } fn() console.log('end') // ③ end
console.log('start') async function fn() { console.log('I am fn Code inside the function') // At this point, the await keyword can be used in the fn function // The promise object returned by pAjax will execute // Assign the contents in parentheses to r1 during resolve(). Continue to execute the code backward const r1 = await myPromiseAjax({ url: 'http://localhost:8888/test/first' }) console.log(r1) // //Demand 2: const r2 = await myPromiseAjax({ url: 'http://localhost:8888/test/second', dataType: 'json' }) console.log(r2) // Demand 3: const r3 = await myPromiseAjax({ url: 'http://localhost:8888/test/third', data: 'name=Jack&age=20', dataType: 'json' }) console.log(r3) } fn() console.log('end')