What is asynchrony? What is synchronization? What is a callback?

asynchronous

If you can get the results straight away it’s synchronization

  • For example, when you register at a hospital, you don’t leave until you get the number
  • The synchronization task may take 10 milliseconds or 3 seconds
  • I won’t leave until I get the results

It’s asynchronous if you can’t get the results directly

  • Wait in front of the restaurant, get the number and go shopping
  • When can WE eat?
  • You can ask at the restaurant every 10 minutes.
  • You can also scan code to receive notifications with wechat (callback)

Asynchronous, for example,

With AJAX, for example

  • After request.send(), you cannot get a response directly
  • Must wait until after the readyState into 4, browser back call reques. The onreadystatechange function
  • To get request.response

The callback callback

  • You write your own function, not a callback
  • The function you write for someone else is a callback
  • Call of the request. The onreadystatechange is addressed to the browser
  • It means you go back and call this function

The callback example

I’m going to give function 1 to another function 2

    function f1(){}
    function f2(fn){
        fn()
    }
    f2(f1)
Copy the code

Asynchrony and callback

associated

  • Asynchronous tasks need to notify JS to get the results when they get them
  • Make JS leave a function address to the browser
  • The browser calls this function address when the asynchronous task is complete
  • Colleagues pass the result as an argument to the function
  • I wrote this function for a browser, so it’s a callback

The difference between

  • Asynchronous tasks require callback functions to notify the result
  • But callbacks are not necessarily limited to asynchronous tasks
  • Callbacks can be used in synchronization tasks
  • Array.foreach (n => console.log(n)) is a synchronization callback

Judge synchronous asynchrony

If the return value of a function is

  • setTimeout
  • AJAX (XMLHTTPRequest)
  • AddEventListener
  • Within these three, then the function is asynchronous

Roll the dice

For example 1

Function (){setTimeout(()=>{return parseInt(math.random () * 6) + 1}, 1000) // undefined}Copy the code

Analysis of the

  • Roll dice () without return, return undefined
  • The arrow function has a return, which returns the actual result
  • So this is an asynchronous function/task

How to get results

Function (fn){setTimeout(()=>{fn(parseInt() * 6) + 1)}, Function f1(x){console.log(x)} // function f1(x){console.log(x)} // function f1(x){console.log(x)} // function f1(x){console.log(x)} // // If the function is inconsistent, you can't roll dice this way (console.log)Copy the code

What if an asynchronous task has two outcomes, success and failure

Two results

Method one: The callback takes two arguments

Fs. ReadFile ('. The / 1. TXT ', (error, data) = > {the if (error) {the console. The log (' failure '); Return} console.log(data.tostring ()) // success})Copy the code

Method two: Make two callbacks

Ajax (' get 'and' / 1. Json, data = > {}, the error = > {}) / / callback function is in front of the success, the function is failed callback ajax (' get ', '/ 1. Json, {success: () = > {}, fail: ()=>{}}) // Accept an object with two keys indicating success and failureCopy the code

The shortcomings of these methods

Both method one and method two are problematic

  • Non-standard, various names, some people use success + error, some people use success + fail, some people use done + fail
  • Easy to go back to hell, code can’t read
  • Error handling is difficult

Callback hell example

    getUser( user => {
        getGroups( user, (groups)=>{
            groups.forEach( (g)=>{
                g.filter(x => x.ownerId === user.id).forEach(x => console.log(x))
            })
        })
    })
Copy the code

Take AJAX wrapping as an example: Explain the use of promises

ajax = (method, url, options)=>{ const {success, Fail} = options // destructor assignment // const success = options.success // const fail = options.fail const request = new XMLHttpRequest() request.open(method, Url) request. The onreadystatechange = () = > {the if (request. ReadyState = = = 4) {/ / success call success, Fail if(request.status < 400){success. Call (null, request.response) }else if(request.status >= 400){ fail.call(null, request, request.status) } } } request.send() } ajax('get', '/xxx', { success(response){}, fail: (Request, status)=>{}}Copy the code

Promise to write

ajax = (method, url, options)=>{ return new Promise((resolve, reject)=>{ const {success, Fail} = options // Destruct assignment const request = new XMLHttpRequest() request.open(method, Url) request. The onreadystatechange = () = > {the if (request. ReadyState = = = 4) {/ / success call success, If (request.status < 400){resolve. Call (null, request.response) }else if(request.status >= 400){ reject.call(null, request, request.status) } } } request.send() }) } ajax('get', '/xxx').then((response)=>{}, (request)=>{})Copy the code

memory

return new Promise((resolve, reject)=>{... })

Summary: How do I make a callback function become an asynchronous function for Promise

The first step

  • return new Promise((resolve, reject)=>{... })
  • Call resolve(result) if the task succeeds
  • Call Reject (error) if the task fails
  • Resolve and reject call success and failure functions

The second step

  • Pass in the success and failure functions using.then(success, fail)

Disadvantages of AJAX in this encapsulation

Post failed to upload data. Procedure

  • Request. Send (where you can upload data)

The request header cannot be set

  • request.setRequestHeader(key, value)

How do you solve it?

  • Take the time to write Ajax perfectly (if you have the time)
  • Using jquery.Ajax (this works)
  • Using Axios (this library is higher than jQuery)

Example axios code

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

Axios advanced usage

JSON automatic processing

  • Axios finds that the content-type of the response is JSON
  • Json.parse is automatically called

Request interceptor

  • You can add something to all requests, such as query parameters

Response interceptor

  • You can add something to all the responses, or even change the content

Can generate different instances (objects)

  • The difference is that the instance can set different configurations for complex scenarios