The article answers the following questions:

  • What is asynchronous and what is synchronous
  • The relationship between callback and asynchrony
  • How do I know if a function is asynchronous
  • What is Promise, and why do we need him
  • Elementary use of promise

What is asynchrony? What is synchronization?

All tasks in the program can be categorized into two categories: synchronous and asynchronous.

If you can get the results directly, it is synchronous, like queuing to buy things, people have to be there, people get the results before leaving. Synchronous tasks are those that are not suspended by the engine and are queued for execution on the main thread. You can perform the next task only after the previous task is completed.

If you can’t get the result directly, it is asynchronous, such as taking the number of queue, queue to do other things before. You can ask every 10 minutes (polling), or you can scan wechat to receive notification, wechat will notify you when the time is close (callback). Asynchronous tasks are those that are put aside by the engine, not into the main thread, but into the task queue. An asynchronous task (in the form of a callback function) is executed on the main thread only if the engine considers it ready to execute (such as an Ajax operation that results from the server).

What is a callback?

A function you write for yourself is not a callback, but a function you write for someone else is a callback. Such as the request. The onreadystatechange function is to the browser back to the calling function (when the end, if a status code is 4… Execute…) So it’s a callback.

Example: 👇

function f1(){}
function f2(fn){} fn()} f2(f1)// I didn't call f1, I passed f1 to F2, and F2 called f1. F1 is the function I wrote f2 to call, so f1 is a callback, f2 is not.
Copy the code

Asynchrony and callback

contact

Callbacks are one way to achieve asynchrony. Asynchronous tasks need to notify JS to get the results when they get them. How? JS can leave a function address (phone number) to the browser, asynchronous task completion, the browser call the function address (call), and the result as a parameter to the function (call said to eat), this function is I write to the browser call, so it is a callback function.

The difference between

Asynchronous tasks require callbacks to notify results, but polling can also notify results, not necessarily callbacks. Callbacks are not always used in asynchrony, but can also be used in synchronous tasks, such as array.foreach (n tail console.log(n)).

How do I know if a function is synchronous or asynchronous

If the return value of a function is

  • setTimeout
  • AJAX (XMLHttpRequest)
  • AddEventListener Event listener

Within these three, then the function is asynchronous

When an asynchronous task has two outcomes

One common way to do this is to have two callbacks corresponding to success and failure, such as in AJAX, which might look like this:

ajax = (method, url, options) = > {
    const success = options.success
    const fail = options.fail
    const request = new XMLHttpRequest()
    request.open(method, url)
    request.onreadystatechange = () = >{
        if(request.readyState === 4) {if(request.status < 400){
                success.call(null, request.response) / / success
            }else if(request.status >= 400){
                fail.call(null, request, request.status)  / / fail
            }
        }
    }
    request.send()
}

ajax('get'.'/xxx', {success(response){}, fail:(request, status) = >{}})// This encapsulation is problematic. Here are just examples of success and failure
Copy the code

Disadvantages of the above approach:

  • No specification. The name can be success+error, success+fail, or even done+ Fail
  • Prone to callback hell
  • Error handling is difficult

Callback hell example:

step1(function (value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        // There may be 20 layers in the middle
      });
    });
  });
});
Copy the code

So promise came along to solve these three problems

Promise

Without further ado, after we use promise, the previous example can be changed to:

ajax = (method, url, options) = > {
	return new Promise((resolve, reject) = >{  // Resolve the essence of callback hell while unifying the name
    const success = options.success
    const fail = options.fail
    const request = new XMLHttpRequest()
    request.open(method, url)
    request.onreadystatechange = () = >{
        if(request.readyState === 4) {if(request.status < 400){
                resovle.call(null, request.response)
            }else if(request.status >= 400){
                reject.call(null, request, request.status)
            }
        }
    }
    request.send()
	})
}

ajax('get'.'/xxx').then((response) = >{}, (request, status) = >{})
Copy the code

In this way, the three problems mentioned at the beginning are solved

Promise basic usage summary

  1. return new Promise((resolve, reject)=>{… }
  2. Call resolve(result) if the task succeeds
  3. Call Reject (error) if the task fails
  4. Resolve and reject call success and failure functions
  5. Pass in the success and failure functions using. Then (success, fail)