On the asynchronous processing in JavaScript

Source: Internet
Author: User

    • In the world of JavaScript, all code is single-threaded
    • Due to this "flaw", all the network operations of JavaScript, browser events, must be performed asynchronously. Asynchronous execution can be implemented with a callback function
    • An asynchronous operation triggers a function call at a later point in time
    • The main asynchronous processing schemes are: callback function (CallBack), Promise, Generator function, async/await.
First, callback function (CallBack)
    • This is the most basic method of asynchronous programming
    • Suppose we have a getData method for getting data asynchronously, the first parameter is the requested url address, and the second parameter is the callback function, as follows:
function getData (URL, callBack) {    //  analog Send network request    setTimeout () = {        //  Suppose Res is the returned data        var res = {            url:url,            data:Math.random ()        }         //  execute callback, pass data as parameter         callBack (res)    )}
    • We pre-set a scenario, assuming we want to request three servers, each request depends on the result of the last request, as follows:
GetData ('/page/1?param=123 ', (res1) = {    console.log (res1)    getData ('/page/2?param=${res1.data } ', (res2) = {        console.log (res2)        getData ('/page/3?param=${res2.data} ', (res3) + = {            Console.log (RES3)     })})
    • As can be seen from the above code, the first request URL address is:/page/1?param=123, the return result is res1.

    • The second request has a URL address of:/page/2?param=${res1.data}, which relies on the res1.data of the first request and returns the result as Res2 '.

    • The URL address for the third request is:/page/3?param=${res2.data}, which relies on the res2.data of the second request and returns the result as Res3.

    • Since the subsequent request relies on the result of the previous request, we can only write the next request to the callback function of the last request, thus forming the usual saying: Callback hell.

Second, publish/Subscribe

We assume that there is a "signal center" in which a task executes, a signal is "released" (publish) to the signal center, and other tasks can "subscribe" to the Signal Center (subscribe) to know when they can start executing. This is called the "Publish/Subscribe Mode" (Publish-subscribe pattern), also known as the "Observer pattern" (Observer pattern)

    • There are several implementations of this pattern, with Ben Alman's Tiny pub/sub, which is a plugin for jQuery
    • First, F2 subscribes to "done" signals to the signal center jQuery.
Jquery.subscribe ("Done", F2);
    • F1 the following rewrite
function F1 () {setTimeout() (function  () {  ///  F1 task code jquery.publish ("Done"  );}
    • jQuery.publish("done")This means that f1 when execution is complete, a signal is issued to the signal center "jQuery "done" , triggering the execution of the F2. In addition, F2 can also unsubscribe () after completion of execution unsubscribe
Jquery.unsubscribe ("Done", F2);
    • This method is similar in nature to "event monitoring", but is significantly better than the latter. Because we can monitor the operation of the program by looking at the message center to see how many signals exist, how many subscribers each signal has.
Third, Promise
    • Promise is a solution to asynchronous programming that is more logical and powerful than traditional solutions-callback functions and events
    • The so-called Promise, simply referred to as a container, holds the result of an event (usually an asynchronous operation) that will end in a future. Syntactically speaking, Promise is an object from which you can get the message of an asynchronous operation. Promise provides a unified API, and various asynchronous operations can be handled in the same way
    • Simply put, the idea is that each asynchronous task returns an Promise object that has a then method that allows you to specify a callback function.
    • Now we are using Promise to re-implement the above case, first of all, we want to encapsulate the method of asynchronous request data into Promise
function getdataasync (URL) {    returnnew Promise ((resolve, reject) = {        setTimeout ( )= = {var res = {url:url, data:Math.random ()} Resolve (res                        )            })}
    • Then the requested code should be written like this
Getdataasync ('/page/1?param=123 ')    . Then (res1= {        console.log (res1)        return getdataasync ('/page/2?param=${res1.data} ')    })    . Then (res2= =        Console.log (res2        return getdataasync ('/page/3?param=${res2.data} ')    })    . Then (res3= > {        console.log (RES3)    })
    • The then method returns a new Promise object, and then the chained call to the method avoids the CallBack callback to Hell
    • But it's not perfect, like we're going to add a lot of then statements, and then we're going to write a callback for each one.
    • If the scene is a little more complicated, for example, every request behind it relies on the results of all previous requests, not just the results of the last request, it is more complicated. In order to do better, Async/await was born, to see how to use async/await to achieve
Iv. async/await
    • The Getdataasync method does not change, as follows

function getdataasync (URL) {    returnnew Promise ((resolve, reject) = {        setTimeout ( )= = {var res = {url:url, data:Math.random ()} Resolve (res                        )            })}
    • The business code is as follows
function GetData () {    var res1 = await getdataasync ('/page/1?param=123 ')    console.log (res1)     var res2 = await getdataasync ('/page/2?param=${res1.data} ')    Console.log (res2)     var res3 = await getdataasync ('/page/2?param=${res2.data} ')    Console.log (RES3)}
    • You can see that using async\await is like writing synchronous code
    • How does contrast Promise feel? is not very clear, but Async/await is based on Promise, because the Async-modified method eventually returns a Promise, in fact, async/await can be seen as using the Generator function to handle asynchronous syntax sugar, let's take a look at How to use the Generator function to handle asynchronous
Wu, Generator
    • First the Async function remains
function getdataasync (URL) {    returnnew Promise ((resolve, reject) = {        setTimeout ( )= = {var res = {url:url, data:Math.random ()} Resolve (res                        )            })}
    • Use the Generator function to write this
function*getData () {    var res1 = yield getdataasync ('/page/1?param=123 ')    Console.log (res1)    var res2 = yield getdataasync ('/page/2?param=${res1.data} ')    Console.log (res2)    var res3 = yield getdataasync ('/page/2?param=${res2.data} ')    Console.log (RES3))}
    • And then we're doing this step-by
var g = getData () G.next (). Value.then (Res1= G.next (res1    ). Value.then (Res2 = = {        g.next (res2). Value.then (()= {            g.next (    ) })})
    • In the above code, we step through the next () method of the Walker, because each next () method returns the Value property of a Promise object
    • So we add the then method to the then method and then run the next method to move the walker pointer until the Generator function is finished, in fact, this process we do not have to manually complete, can be encapsulated into a simple actuator
function Run (gen) {    var g = Gen ()    function  Next (data) {        var res = g.next (data)        ifreturn  res.value        + = {            Next (data)}        )    }    Next ()}

The Run method is used to automatically run the asynchronous Generator function, which is actually a recursive procedure call process. So we don't have to manually execute the Generator function. With the Run method, we only need to run the GetData method like this

Run (GetData)

In this way, we can encapsulate the asynchronous operation inside the Generator function and use the Run method as the self-executor of the Generator function to handle the asynchronous. In fact, it is not difficult to find that the Async/await method compared to Generator processing asynchronous way, there are many similarities, but async/await in the semantic aspect more obvious, while async/await do not need our handwriting actuator, The interior has been packaged for us, which is why async/await is the Generator function that handles the asynchronous syntax of sugar.

On the asynchronous processing in JavaScript

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.