当前位置:网站首页>Asynchronous and promise

Asynchronous and promise

2022-07-05 02:07:00 Cherish time, Xiao Li

Asynchronous with Promise( Interview required )

AJAX(Async JavaScript And XML)
Content :Ajax Asynchronous programming in js Unified solution in (js Asynchronous programming model ) Promise

What is asynchronous ? What is synchronization ?

Sync : You can get the results directly
For example, you register in the hospital , Get the number before you leave the window .
Synchronization tasks may consume 10ms, May also require 3s
In short, you won't leave until you get the result

asynchronous : You can't get the results directly
For example, you wait at the door of the restaurant , Get the number and go shopping
When can we really eat ?
You can every 10min Go to the restaurant and ask ( polling )
You can also scan the code and receive the notification via wechat ( Callback )
Asynchrony usually refers to " Asynchronous plus callback "
give an example
1. With ajax For example
request.send() after , Not directly response
Don't believe it console.log(request.response) try
We have to wait until readState Turn into 4 after , Browser call back
request.onreadystatechange function
We can get request.response
This is similar to the process that the restaurant sends you wechat reminders

Add : stay js It takes about hundreds to send a network request and get a response ms~1/2s
 Insert picture description here

getJSON.onclick = () => {
  ...
  request.send()
  console.log(request.response) // Can't get... Directly response
  setTimeout(() => { //2s Get back response
    console.log(request.response)
  }, 2000)
}
 After downloading, the browser will call back request.onreadystatechange function 
 So the above code is equivalent to 
 request.onreadystatechange = () => {
   if (request.readyState === 4 && request.status == 200) {
       console.log(request.response)
       ...
   }
 Print out response After is 3s after 

2. Callback callback
The function you write for yourself , Not a callback
Functions you write for others , It's a callback
request.onreadystatechange Namely I write to the browser to call Of
It means that the browser will adjust this function back
「 come back 」 Also have 「 future 」 It means , Such as 「 I'll treat you to dinner later 」
give an example
1. Put function 1 Give another function 2

function f1(){}
function f2(fn){
  fn()
}
f2(f1)

I call f1 No, ? No,
I put f1 Pass to f2 Have you ? Yes
f2 call f1 Have you ? Adjusted
that f1 Am I writing to f2 Called function ? yes , therefore f1 It's a callback
There is no call 、 Passed it on to others 、 Someone else called
Add

//request.setCallback(onreadystatechange)
request.onreadystatechange

Whether it is a parameter is not a big problem , Write the same effect directly
However, it is generally not recommended to put it on the object , It is best to pass it as a parameter , Prevent others from not knowing

Bowing 1, If I send it to f2 The parameter of is not a function ?
Will report a mistake :fn Not a function . Don't you know your mistake when you see it
Bowing 2

function f1(x){
  console,log(x)
}
function f2(fn){
  fn(' Hello ')
}
f2(f1)

f1 How could there be a x Parameters
fn(‘ Hello ’) Medium fn Namely f1 Right
fn(‘ Hello ’) Medium ’ Hello ’ Will be assigned to the parameter x Right
therefore x Namely ’ Hello ’.x It means the first one 1 It's just a parameter

The relationship between asynchrony and callback

Callback is that I pass a function to you Or transfer to the global function request On
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 ( Phone number ) To the browser
When the asynchronous task is completed, the browser can call the function address ( Make a phone call )
At the same time, the result is passed to the function as a parameter ( It said on the phone that I could come and eat )
This function I wrote to the browser to call , So it's a callback function
difference
Asynchronous tasks often use callback functions to notify the results , But you don't have to use callback . You can also use rotation
Callback functions are not necessarily only used in asynchronous tasks , It can also be used in synchronization tasks
array.forEach(n=>console.log(n)) It's synchronous callbacks
array How many elements are there in it forEach It calls the function n How many times

Judge synchronous and asynchronous

How to distinguish whether a function is synchronous or asynchronous ?
According to features or documents
If the return value of a function is here 3 Something inside , So this function is asynchronous
setTimeout
Ajax( namely XMLHttpRequest)
AddEventListener
Wait a minute , I heard that Ajax Can be set to synchronous
silly X The front end just Ajax Set to synchronous , This will cause the page to jam during the request .

Example : asynchronous 1 Processing of results
1s After the return 1~6 The random number

function  Dice (){
     
  setTimeout(()=>{
     
    return parseInt(Math.random() * 6 ) + 1 
  },1000)
  //return undefined
}

const n= Dice ()
console.log(n) //undefined

Dice () Didn't write return, That's it return undefined
The arrow function has return, Return to the real result
Pay attention to this 2 individual return Belong to different functions
So this is an asynchronous function / Mission

How can we get asynchronous results (1~6 The random number )?
You can use callback . Write a function , Then give it the function address

function f1(x){console.log(x)}
 Dice (f1)

Then I asked Roll dice function After getting the result Take the result as a parameter Pass to f1

function  Dice (fn){
     
  setTimeout(()=>{
     
    fn(parseInt(Math.random() * 6 ) + 1) // Send the result to fn
  },1000)
}

Pass the results on to fn, At this time, the results can be output .

Reduced to arrow function .f1 Only once after the declaration , So you can delete f1
Optimization techniques : When the function is declared only once , It can be simplified to anonymous functions

function f1(x){
    console.log(x)}
 Dice (f1)
 Change it to 
 Dice (x=>{
    
  console.log(x)
})
 Simplify it to 
 Dice (console.log)

If the number of parameters is inconsistent, it cannot be simplified like this , There is an interview question

 Dice (x,y=>{
  console.log(x)
})

Interview questions

const array=['1','2','3'].map(parseInt)
console.log(array)
 Output results :[1, NaN, NaN]
 Restore 
const array=['1','2','3'].map((item,i,arr)=>{
    
  return parseInt(item,i,arr)
  //parseInt('1',0,arr)=>1
  //parseInt('2',1,arr)=>NAN  There is no single digit 2 So get NAN
  //parseInt('3',2,arr)=>NAN  Binary does not 3 So get NAN
})
console.log(array)
 Output results :[1, NaN, NaN]

map receive 3 Parameters
hold 2 As 1 Hexadecimal numbers are parsed ,2 The hexadecimal number is only 0 and 1,1 The hexadecimal number is only 0,10 It's just 0~9. Because there is no one base 2 So the result is not a number NAN.

Simplify correctly

const array=['1','2','3'].map((item,i,arr)=>{
    
  return parseInt(item)
})
console.log(array)
 Output results :[1, 2, 3]
 Abbreviation 
const array=['1','2','3'].map((item=>parseInt(item))
console.log(array)

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
Why does asynchronous use callbacks ? In order to get the results that cannot be obtained directly , You must use a callback / polling

Promise Usage of

Promise It is a unified solution for the front-end to solve asynchronous problems , asynchronous 2 results ( success 、 Failure ) To deal with
If the asynchronous task has 2 Results success and failure , What do I do ?
Method 1: The callback takes two parameters (node.js This is the scheme used , Receive two parameters )

fs.readFile('./1.txt',(error,data)=>{
    //2 Parameters : The mistake of failure , Successful results 
  if(error){
    console.log(' Failure '); return}
  console.log(data.toString()) // success 
)

Method 2: Make two callbacks

ajax('Get','./1.json',data=>{
    },error=>{
    })
// The previous function is a successful callback , The following function is the failure callback 
 perhaps 
ajax('Get','./1.json',{
    
  success:()=>{
    },fail:()=>{
    }
})
// Accept an object , There are two objects  key  Indicates success and failure 

No matter how 1 Or the way 2 All have problems , Yes 3 Disadvantages ( Callback 3 A question )
1. There are no written regulations . There are many different names , Someone uses it success+error, Someone uses it success+fail perhaps done+fail
2. It's easy to see Back to hell , The code becomes incomprehensible
3. It's hard to do Error handling
Call back to hell, for example

getUser(user=>{
    
  getGroups(user,(groups)=>{
    
    groups.forEach((g)=>{
    
      g.filter(x=>x.ownerId===user.id).forEach(x=>console.log(x))
    })
  })
})
 This is only a four level callback , You can imagine 20 Layer callback ?

Is there any way to solve this 3 A question ? use promise
Specifies the name or order of callbacks
Refuse to call back to hell , Make code more readable
It's easy to catch errors

promise Thought is in 1976 Put forward in , Later, it was copied by the front end .
promise What is it? ?1976 A design pattern in ( The well written code takes a name )
With ajax For example , explain promise Usage of
Example : Write a callback package

//1.ajax The definition of 
ajax=(method,url,options)=>{
    
  const {
    success,fail}=options // An analytic assignment , from options I'll get success and fail this 2 Callback functions 
  const request=new XMLHttpRequest() // Global variables request
  request.open(method,url)
  request.onreadystatechange = () => {
    
    if (request.readyState === 4) {
    
    // If successful, call success, Fail to call fail
      if(request.status < 400){
    
      // Generally speaking, it will not appear 300 Of ,300 Should not appear here ,300 Will send another request 
        success.call(null,request.response)
      }else if(request.status >= 400){
    
        fail.call(null,request,request.status)
      }
    }
  }    
    request.send()  
}
//2.ajax Use 
ajax('Get','/xxx',{
    
  success(response){
    },fail:(request,status)=>{
    }
  //ES6 grammar : On the left is function abbreviation , On the right is the arrow function 
})

ES 6 grammar : An analytic assignment

const {
    success,fail}=options // An analytic assignment , from options I'll get success and fail this 2 Callback functions 
  // Equivalent to 
  //const success=options.success
  //const fail=options.fail

Promise It's silly to say this code , Let's change it 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)=>{})

Although it is also a callback , But you don't need to remember success and fail 了
then Of the 1 One parameter is success, The first 2 One parameter is fail
promise It stipulates that only one parameter can be returned for success or failure
ajax() What did you return ?
Returns a message containing .then() Object of method
Then how to get this containing .then() The object of ?
Then we need to transform ajax The source of the

ajax=(method,url,options)=>{
    
  return new Promise((resolve,reject)=>{
     //1 It's about 
    const {
    success,fail}=options 
    const request=new XMLHttpRequest()
    request.open(method,url)
    request.onreadystatechange = () => {
    
      if (request.readyState === 4) {
    
        if(request.status < 400){
    
          resolve.call(null,request.response) //2 It's about 
        }else if(request.status >= 400){
    
          reject.call(null,request,request)   //3 It's about 
        }
      }
    }    
      request.send()  
  })
}

accord with promise canonical ajax call , Let the asynchronous function of callback become promise The asynchronous function of
step
The first 1 Step ( Definition time ), add return new Promise((resolve,reject)=>{…})
The task was successfully adjusted resolve(result), Fail tone reject(error)
resolve and reject The success and failure functions are called again
The first 2 Step ( When using ), Use .then(success,fail) Pass in success and failure functions
How to use Promise?
Memorize 5 Word return new promise((resolve,reject)=>{...}

summary

Memorize :return new promise((resolve,reject)=>{ Called on success resolve, Call... On failure reject}
//return Constructors ( Parameters )
About asynchrony
1. If JS You can't get the result of a function directly , You can execute other code first , Wait until the result arrives , This is asynchronous
2. Asynchronous results can be obtained by polling , Polling is to ask whether the result has been obtained
3. Asynchronous results can be obtained through callback , Generally speaking, the result will be used as the first parameter of the callback
4. The advantage of asynchrony is that the waiting time can be used to do other things
About callback
1. Functions that meet certain conditions are called callbacks , For example, I write a function A, Pass it to another function B call , So the function A It's a callback
2. Callbacks can be used to synchronize tasks , Not necessarily for non asynchronous tasks
3. Sometimes callbacks can also be passed to an object , Such as request.onreadystatechange, Wait for the browser to call
About Promise
1.Promise Not invented by the front end , It is the unified solution for the front-end to solve the asynchronous problem .
2.window.Promise It's a global function , Can be used to construct Promise object
3. Use return new Promise((resolve, reject)=> {}) You can construct a Promise object
Constructed Promise Object contains a .then() Function attribute

Add : Be careful Promise Cannot be cancelled . In order to solve the cancellation promise This problem ,axios I thought of a way to use CancleToken.
The principle is to number the request , Suppose 10 individual promise, among 9 No more . Just put id by 1~9 Of promise Corresponding ajax Request termination .promise Or do , It's just ajax No more .axios The cancellation is not promise It's a request .axios.CancleToken

About return new Promise((resolve, reject)=>{…}) Medium resolve and reject
1.resolve and reject It can be changed to any other name , Not affecting use , But it's usually called these two names .
2. Call... When the task is successful resolve, Call... When it fails reject
3.resolve and reject Only one data is received , and this It's empty , Should not use this
4.resolve and reject Not at all .then(success, fail) Inside success and fail,resolve Going to call success,reject Going to call fail

We packaged it ajax The shortcomings of
1.post Unable to upload data request.send( Here you can upload data )
2. Cannot set request header request.setRequestHeader(key,value)
How to solve it ?
1. Use axios ( recommend )
2. Use jQuery.ajax
We need to master jQuery.ajax Do you ? no need , Write a blog listing the functions , You can forget jQuery 了
3. Take your time to ajax Write perfect

axios library

Chinese document The original English text

Axios It's based on promise Of HTTP library , Can be used in the browser and node.js in .
Up to date Ajax library ,Vue、React They're all using it .
This cubby jQuery Doggerel , Now professional front-end is used axios, It copied jQuery The idea of packaging .
It is recommended to learn a library by blogging axios Quick reference table

Code example

axios.get('/5.json')
  .then(response=>
    console.log(response)
)

axios
This is a dedicated operation AJAX The library of
axios.get(’/xxx’) Return to one Promise object
axios.get(’/xxx’).then(s, f) Call... When the request is successful s, Failed use call f

axios Advanced usage
1.JSON Automatic processing
axios How to find the response Content-Type yes json
Will automatically call JSON.parse
So the right settings Content-Type It's a good habit
2. Request interceptor

You can add something to all the requests , For example, add query parameters

As long as it's right in this function config Make some changes , Then all your requests will be tampered with by yourself .
for instance , We need to add a parameter to the request , No matter what the request is, you need to add a parameter .
Then you can add an interceptor .

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

3. Response interceptors

You can add something to all the responses , Even change the content

function(response){ return response;} Get the original response data . If you are not satisfied with the data , It can be modified . So you can test it .

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });

4. You can generate different instances ( object )
Different configurations can be set for different instances , For complex scenes

instance Namely axios Replica

var instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

encapsulation ! encapsulation ! encapsulation !
Junior programmers learn API( Include Vue/React Of API)
Intermediate programmers learn how to package
Senior programmers build wheels

How to use Axios? Set the following reference to use
open BootCDN Search for axios-> choice axios.min.js, Click replication <script> label
 Insert picture description here

See the sample
console.log(axios) The console prints out the function , explain axios There is , In this way, the quotation is successful ( Reference script ).
axios.get(’/xxx’) The request was sent successfully ( Because there is no content, it is 404)
 Insert picture description here

Interview questions
Why do we use promise ah , Can you tell me the reason ?
Ideas :promise It can solve the callback 3 A question
1. Specifies the name or order of callbacks
2. Refuse to call back to hell , Make code more readable
3. It's easy to catch errors

原网站

版权声明
本文为[Cherish time, Xiao Li]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140949197205.html