What is asynchrony? What is synchronization

asynchronous

If you can get the results directly, it’s synchronous;

For example: register at the hospital and leave the window when you get the number.

If you can’t get the results directly, it’s asynchronous.

Example: Wait at the restaurant so you can go shopping when you get the number

When can we actually eat?

You can ask in the restaurant every 10 minutes.

You can also scan code to receive notifications with wechat (callback)

The callback callback

A callback is a function that is written but not called.

For example:

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

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

Analysis:

  • I call thef1No? Answer: No call
  • I put thef1To pass tof2Is there anyone else? Answer: the pass
  • f2Call thef1No? A:f2Call thef1
  • So,f1That’S what I wrotef2Function called, so,f1Is the callback.

Asynchrony and callback

associated

  • Asynchronous tasks need to notify JS to get the results when they get them
  • How to notify?
  • You can ask JS to leave a function address to the browser
  • The browser calls this function address when the asynchronous task is complete
  • It also passes the result as an argument to the function
  • This is a callback function that I wrote for the browser to call

The difference between

  • Asynchronous tasks need to use callback functions to notify results, or polling can be used
  • But callbacks are not necessarily limited to asynchronous tasks
  • Callbacks can be used in synchronization tasks
  • arry.forEach(n => console.log(n))It’s a synchronous callback

Judge synchronous asynchrony

If the return value of a function is

  • setTimeout
  • AJAX(i.e., the XMLHttpRequest)
  • AddEventListener
  • If the return value is inside these three things, then the function is asynchronous

AJAX can be set to synchronous, but doing so will cause the page to freeze during requests. Do not use it.

For example 1

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

Analysis of the

  • Roll the dice ()Didn’t writereturn, that is,return undefined
  • The arrow function has itreturnReturns the real result
  • So this is an asynchronous function/task

For example 1 to continue

constN = roll the diceconsole.log(n) //undefined
Copy the code

How do I get asynchronous results

  • A: You can use a callback. Write a function, and give it the address of the function
function f1(x){console.log(x)} Roll dice (f1)Copy the code
  • And then I asked the dice roll function to get the result and pass it in as an argumentf1
functionRoll the dice,fn){
    setTimeout(() = >{
        fn(parseInt(Math.random() * 6) +1)},1000)}Copy the code

Simplified arrow function

Since f1 is only used once after the declaration, you can delete f1

function f1(x){console.log(x)} Roll dice (f1)Copy the code

Change to

Roll the dice,x= > {
    console.log(x)
 })
Copy the code

To simplify the

Roll the dice,console.log)
// If the number of arguments is inconsistent, this cannot be simplified
Copy the code

summary

  • Asynchronous tasks cannot get results
  • So we pass a callback to the asynchronous task
  • The callback is invoked when the asynchronous task completes
  • Call with the result as an argument

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

Two results

  • Method one: The callback takes two arguments
fs.readFile('./1.txt'.(error, data) = >{
    if(error){console.log('failure'); return}
    console.log(data.toString()) / / success
})
Copy the code
  • Method 2: Pass two callbacks
ajax('get'.'/1.json', data()=>{}, error()=>{})
// The first function is a success callback and the second function is a failure callbackAnother form: Ajax ('get'.'/1.json', {
    success: () = >{}, fail: () = >{}})// Accept an object with two keys representing success and failureCallbacks do not have to be in the form of functions; they can also be in the form of objectsCopy the code
  • The shortcomings of these methods

No matter method one or method two, there is a problem

  1. Non-standard, various names, some people use success+error, some people use success+fail, some people use done+fail
  2. Prone to callback hell, code becomes unreadable
  3. Error handling is difficult

Promise

Promise is a unified front-end solution to asynchronous problems

Use AJAX wrapping as an example to explain the use of promises

ajax = (method, url, options) = >{ 
    const {success, fail} = options // Destruct assignment
    const request = new XMLHttpRequest()
    request.open(method, url)
    request.onreadystatechange = () = >{ 
        if(request.readyState === 4) {//成功就调用success,失败就调用fail
            if(request.status < 400){ 
              success.call(null, request.response) 
            }else if(request.status >= 400){ 
              fail.call(null, request, request.status)
            }
        }
    }
    request.send() 
 } 
Copy the code
ajax('get'.'/xxx', { 
    success(response){}, fail: (request, status) = >{}})// The function abbreviation is on the left and the arrow function is on the right
Copy the code

I’ll write it as Promise

ajax('get'.'/xxx', { 
    success(response){}, fail: (request, status) = >{}})// Two callbacks are used, as well as success and fail
// Make a promise
ajax('get'.'/xxx') 
  .then((response) = >{}, (request) = >{}) // Promise specifies that either a successful callback or a failed callback can accept only one parameter
Copy the code

It is also a callback, but you do not need to remember success and FAIL;

The first argument to then is success, and the second argument to then is fail.

Ajax () returns an object containing the.then() method,

So how do you get this object that has dot then?

Then you need to modify the 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) {// Call resolve on success, reject on failure
        if(request.status < 400){ 
          resolve.call(null, request.response) 
        }else if(request.status >= 400){ 
          reject.call(null, request) 
        }
      }
    } 
    request.send() 
  })
}
Copy the code

summary

How to change a callback to an asynchronous functionpromiseAsynchronous function of?

  1. The first step
  • return new promise ((resolve, reject)=>{... })
  • Called if the task succeedsresolve(result)
  • Called if the task failsreject(error)
  • resolveandrejectThe successful and failed functions are called again

resolveandrejectIs not.then(success, fail)The inside of thesuccessandfail, resolve calls success, reject calls fail.

  1. The second step
  • use.then(success, fail)Pass in the success and failure functions

Promise is used more advanced, and then more

The disadvantages of AJAX encapsulated above

  • Post failed to upload data. Procedure

Request. Send (where you can upload data)

  • The request header cannot be set

request.setRequestHeader(key, value)

  • How to solve

Using jquery. ajax (although jquery. ajax is perfect and powerful, it is outdated and more axios is used)

Use Axios (see Fang Yinghang’s blog)

Expand knowledge:

Promise can’t be cancelled, but Axios can, because Axios invented cancelToken.