What is asynchronous ? What is synchronization
asynchronous
If you can get the results directly , It's synchronization ;
give an example : Register at the hospital site , Get the number before you leave the window .
If you can't get the results directly , It's asynchronous .
give an example : Wait at the restaurant door , After you get the number, you can go shopping
When can we really eat ?
You can every 10 Go to the restaurant and ask in minutes ( polling )
You can also scan the code and use wechat to receive notifications ( Callback )
Callback callback
Write but don't call , Functions called to others , It's a callback .
give an example :
Put function 1 Give another function 2
function f1(){}
function f2(fn){
fn()
}
f2(f1)
Copy code
analysis :
- I called
f1
No, ? answer : There is no call - I put
f1
Pass tof2
( others ) Have you ? answer : Yes f2
Calledf1
No, ? answer :f2
Calledf1
- that ,
f1
I wrote it tof2
Called function , therefore ,f1
It's a callback .
The relationship between asynchrony and callback
relation
- Asynchronous tasks need to be notified when they get results JS Here's the result
- How to inform ?
- It can make JS Leave a function address for the browser
- When the asynchronous task is completed, the browser can call the function address
- At the same time, the result is passed to the function as a parameter
- This function I wrote to the browser to call , So it's a callback function
difference
- Asynchronous tasks need to use callback functions to notify results , You can also use polling
- But callback functions don't have to be used only in asynchronous tasks
- Callbacks can be used in synchronization tasks
arry.forEach(n => console.log(n))
It's synchronous callbacks
Judge synchronous and asynchronous
If the return value of a function is in
setTimeout
AJAX
( namely XMLHttpRequest)AddEventListener
- If the return value is inside these three things , So this function is asynchronous
AJAX Can be set to synchronous , But doing so will cause the page to get stuck during the request , Do not use .
give an example 1
function Dice (){
setTimeout(()=>{
return parseInt(Math.random() * 6)+1},1000)
// return undefined
}
Copy code
analysis
Dice ()
Didn't writereturn
, That's itreturn undefined
- The arrow function has
return
, Return to the real result - So this is an asynchronous function / Asynchronous task
give an example 1 To continue
const n = Dice ()
console.log(n) //undefined
Copy code
How to get asynchronous results
- answer : You can use callback . Write a function , Then give it the function address
function f1(x){console.log(x)}
Dice (f1)
Copy code
- Then I asked the roll dice function to get the result and pass the result as a parameter to
f1
function Dice (fn){
setTimeout(()=>{
fn(parseInt(Math.random() * 6)+1)},1000)
}
Copy code
Simplified arrow function
because f1
Only once after the declaration , So you can delete f1
function f1(x){console.log(x)}
Dice (f1)
Copy code
Change to
Dice (x => {
console.log(x)
})
Copy code
Simplify it to
Dice (console.log)
// If the number of parameters is inconsistent, it cannot be simplified like this
Copy code
Summary
- Asynchronous tasks don't get results
- So we send a callback to the asynchronous task
- Call the callback when the asynchronous task is completed
- When called, take the result as a parameter
If an asynchronous task has two results , Success or failure , What do I do
Two results
- Method 1 : The callback takes two parameters
fs.readFile('./1.txt',(error, data)=>{
if(error){console.log(' Failure '); return}
console.log(data.toString()) // success
})
Copy code
- Method 2 : Pass two callbacks
ajax('get', '/1.json', data()=>{}, error()=>{})
// The previous function is a successful callback , The following function is the failure callback
Another form :
ajax('get', '/1.json', {
success: ()=>{}, fail: ()=>{}
})
// Accept an object , There are two objects key Indicates success and failure
Callbacks don't have to be in the form of functions , You can also use the form of objects
Copy code
- The shortcomings of these methods
Whether method one or method two , All have problems
- No specification , There are many different names , Someone uses it success+error, Someone uses it success+fail, Someone uses it done+fail
- Prone to callback hell , The code becomes unintelligible
- It's hard to do error handling
Promise
promise It is a unified solution for the front-end to solve asynchronous problems
With AJAX For example , explain Promise Usage of
ajax = (method, url, options)=>{
const {success, fail} = options // An analytic assignment
const request = new XMLHttpRequest()
request.open(method, url)
request.onreadystatechange = ()=>{
if(request.readyState === 4){
// If successful, call success, Fail to call fail
if(request.status < 400){
success.call(null, request.response)
}else if(request.status >= 400){
fail.call(null, request, request.status)
}
}
}
request.send()
}
Copy code
ajax('get', '/xxx', {
success(response){}, fail: (request, status)=>{}
}) // On the left is function abbreviation , On the right is the arrow function
Copy code
Change to Promise How to write it
ajax('get', '/xxx', {
success(response){}, fail: (request, status)=>{}
})
// Two callbacks are used above , Also used. success and fail
// Change to promise How to write it
ajax('get', '/xxx')
.then((response)=>{}, (request)=>{}) //promise Specifies that both successful callback and failed callback can only accept one parameter
Copy code
Although it is also a callback , But you don't need to remember success and fail 了 ;
then
The first parameter of is success
,then
The second parameter of is fail
;
ajax()
Returns a message containing .then()
Object of method ,
So how do you get this containing .then
The object of ?
Then we need to transform ajax Source code
ajax = (method, url, options)=>{
return new Promise((resolve, reject)=>{
const {success, fail} = options
const request = new XMLHttpRequest()
request.open(method, url)
request.onreadystatechange = ()=>{
if(request.readyState === 4){
// If successful, call resolve, Fail to call reject
if(request.status < 400){
resolve.call(null, request.response)
}else if(request.status >= 400){
reject.call(null, request)
}
}
}
request.send()
})
}
Copy code
Summary
How to turn the asynchronous function of a callback into promise
The asynchronous function of ?
- First step
return new promise ((resolve, reject)=>{...})
- If the task succeeds, call
resolve(result)
- If the task fails, call
reject(error)
resolve
andreject
The success and failure functions are called again
resolve
and reject
Not at all .then(success, fail)
Inside success
and fail
,resolve call success,reject call fail.
- The second step
- Use
.then(success, fail)
Pass in success and failure functions
promise More advanced usage , And then more
The above encapsulated AJAX The shortcomings of
- post Unable to upload data
request.send( Here you can upload data )
- Cannot set request header
request.setRequestHeader(key, value)
- How to solve
Use jQuery.ajax ( although jQuery.ajax Very perfect and powerful , But it's out of date , More in use axios)
Use axios( For reference, Fang Yinghang blog )
Expand your knowledge :
promise It can't be cancelled , however axios May cancel , because axios Invented cancelToken
.