Process control: JQ deferred and ES6 promise use novice to pit!

Time:2021-6-17

Process control: JQ deferred and ES6 promise use novice to pit!

thank youn͛i͛g͛h͛t͛i͛r͛e͛A big point aboutPromiseincatchMistakes that are not used properly, and paste the articles highly recommendedRookies and higher order errors in promiseThe article explains some of them in detailPromiseMistakes and guidance in use. In addition, the correction is added later.

Start with jQuery $. Deferred()

When it comes to asynchronous process control, the most commonly used is deferred of JQ. What is deferred? It doesn’t matter if you don’t know. Print it directly from the console

Process control: JQ deferred and ES6 promise use novice to pit!

Oh! You can see that after $. Deferred(), there is an object whosebelowWith a familiardone, fail, alwaysAre you familiar with the words? you ‘re right! If you often use ajax, you will often come into contact with these goods). Of course, not only that, but also the most importantrejectandresolveMethods. Speaking of these two methods, we have to introduce the state mechanism of deferred. In fact, it’s very simple. After instantiation, use thestateMethod($.Deferred().state())There are three states

  • Before resolving / reject, the return value is pending

  • Resolved is executed, and the return value is resolved

  • After executing reject, the return value is rejected

Come straight and try to use it! Here we assume that a random delay is executedsetTimeoutAsynchronous operation of,staysetTimeoutAfter the end of asynchronous operationAccording to the delay size, make different responses! code:

function log (msg) {
    console.log(msg);
}
//Wrapping an asynchronous operation
var Async = function () {
    //Generate a delay of 0 to 5 seconds
    var delay = Math.floor(Math.random() * 5);
    //Create a deffered object
    var dfd = $.Deferred();
    //An asynchronous operation is called here
    setTimeout(function(){
        if (delay <= 2) {
            //Set DFD status to resolved
            DFD. Resolve ('everything is OK ');
        } else {
            //Set DFD status to rejected
            DFD. Reject ('timeout ');
        }            
    }, delay * 1000)
    //Here, we want to return the promise object under deferred, and the reason for the dererred object will be explained below
    return dfd.promise();
}

Async()
    .done(function (data) {
        Log (data) // if the delay is no more than three seconds, output the data in DFD. Resolve() 'everything is OK
    })
    .fail(function (err) {
        Log (ERR) // otherwise, the data in DFD. Reject() will be output 'timeout 
    })
    .always(function () {
        Log ('execution completed ')// Always output 'execution finished
    })

Try to understand the whole process

  1. In an operationBefore we startCreate aDeferredObject, and then perform the operation

  2. The operation room can be executed by DFD according to the situationreloveperhapsrejectMethod changes state and passes in data

  3. Finally, a project object under the DFD object is returned. Here, the DFD object is not returned directly because the state of the DFD object can be changed after the first resolve or reject (but the data in it is subject to the first time)!!

  4. Use after operationdoneandfailMethod respectively accepts the status and data of resolve and reject (one-to-one correspondence), and then executes the callback (in fact, there are 1.8 more)thenMethod, which takes two parameters. The first parameter isresolveThe second isreject(of)

  5. alwaysIt doesn’t matterresolvestillrejectIt will be carried out.

Tell me a bad analogy

I am a quality inspection worker in an assembly line workshop. On a normal day, a batch of teddy bears came. Well, the next thing should be like this

  1. There’s an inspection target($.Dererred())And then you don’t know if it’s good or bad

  2. I rely on my decades of New Oriental cooking skills to test products and label good products as qualified(DFD. Res * olve (qualified label))The defective products should be labeled back to the factory*(DFD. Reject (return label and reason)

  3. Then pass the good and defective products have come to their own packaging, make a good bag, can’t change the label inside(dfd.promise())Go to your next destination(return dfd.promise)

  4. Then liangpin comes to bear child(.done())The defective products returned to the factory(.fail())In the end, no matter where the teddy bear goes, it will be cut open(.always()Well, it’s a bit far fetched here.)

Here is another picture to explain!

Process control: JQ deferred and ES6 promise use novice to pit!

It’s also worth mentioningalwaysWhen I use it in practice, I find that it is always in thedoneandfailIt is executed after the callback (assuming synchronization) in.

Golden cactus, silver cactus, let’s welcome ES6 promise

Just like above, print it first!

Process control: JQ deferred and ES6 promise use novice to pit!

You can see that there are also familiar programs under promiseresolveandrejectMethod, like JQDeferredQuite similar! But what’s missing?doneperhapsfailWhat about process control??

It’s not urgent. It’s actually unfoldingprototypeYou can see it on the prototypethenThere’s no way( It’s like the one after jq1.8thenBut I think it’s JQPromise(right)
Process control: JQ deferred and ES6 promise use novice to pit!

Promise is actually a constructor, which is the previous example. Here we go in three steps

var Async = function () {
    //The first step is to create a new promise object in which the required asynchronous operations are performed
    var prms = new Promise(function(resolve, reject){
        //Generate a delay of 0 to 5 seconds
        var delay = Math.floor(Math.random() * 5);
        //An asynchronous operation is called here
        setTimeout(function(){
            //Second, set project to resolve or reject according to the situation
            if (delay <= 2) {
                //Set DFD status to resolved
                Resolve ('everything's OK ');
            } else {
                //Set DFD status to rejected
                Reject ('timeout ');
            }            
        }, delay * 1000)
    })
    //The third step is to return the promise object
    return prms
}

//Here comes the powerful
Async()
    //Then accepts two functions to handle the resolve and reject states respectively
    .then(
    function(data) {
        Console. Log (data) // everything is OK!
    }, 
    function(err) {
        Console.log (ERR) // timeout!!
    })

At first glance, it seems to be the same asDererredIt can’t be more like,, but if you are careful, you can find that we directly return in the functionprmsThis object, instead of wrapping it up like before… yes! becausePromiseOnce the state is given for the first time, it can’t be changed. It’s a lot easier. But the question is, why should I choose to use itPromiseWhat about??

Let’s put it this way,It’s native, it’s native, it’s native!AndCan chain call!We can take each onethenperhapscatchAs a processor, like this

Async()
    //For the time being, we only deal with resolve
    .then(function(data) {
        Console. Log (data) // everything is OK!
        Return promise. Resolve ('anything ');
    })
    //The next then processor receives data from the previous processor
    .then(function(data2) {
        Console. Log (data2) // anything
        Return promise. Reject ('wrong data ');
    })
    ...

yes! I’m not wrong, actuallythenYou can do it in therereturnotherpromiseObject transfer and data transfer! What’s more, you can even return nothing, like this

Async()
    .then(function(data) {
        Console. Log (data) // everything is OK!
    })
    //If the processor above does not return anything, it will return a resolve (undefined) by default
    //Then the following processor will receive the resolve (undefined)
    .then(function(data2) {
        console.log(data2) // undefined
        //Although there is no data to process, you can still do some things here, such as
        Return promise. Reject ('wrong data ');
    })
    //Dada, catch is on the stage. Here, catch is used to process the reject issued by the last then processor
    .catch(fucntion(err){
        Console. Log (ERR) // error data
        What about returning a string directly? "
    })
    //The last catch processor returns a string, which will be accepted by the next processor
    //It's equivalent to resolve ('How about returning a string directly?)
    .then(function(data3){
        Console. Log (data3) // how about returning a string directly?
    })
    //OK, then let's try to connect a catch processor without returning anything
    .catch(function(err2){
        console.log(err2) 
        //Can we guess what the output is, undefined?
        //Wrong. In fact, nothing will be output here, because this catch receives resolve
        //But instead of swallowing the resolve, it chooses to skip, for example, we'll go back here
        Return promise. Resolve ('This string will be skipped ')
    })
    //This is followed by a then processor. What data does it receive
    //In fact, it is not the resolve returned by the previous catch ('This string will be skipped ')
    //Instead, the then processor before catch returns resolve (undefined) by default
    .then(function(data4){
        console.log(data4) // undefined
    })

It’s a little dizzyProcess control: JQ deferred and ES6 promise use novice to pit!

Let’s sort it out in one sentence

There will be a string under the chain adjustmentthenandcatchThesethenandcatchThe processor willIn orderacceptLast processorThe generated return value, and according to theState of incomingdoDifferentResponse, either skip or process (so thecatchProcessor skipped)

PS: we use it abovethenThe processor has only one function parameter, so it will only processresolveState, if it’s twothenYou can handle itrejectIt’s too late.

Updated on May 11

catchAttention in use

In the code above, we introducecatchProcessor, I thoughtcacth()yesthen(null, ...)In fact, it’s not entirely correct to say that (on the functional level, these two are exactly the same, right – both are processingrejectAnd exception), but to the actual useRookies and higher order errors in promiseThe article gives a clear proof of the situation

First of all, we only deal with exceptions. The following two are equivalent

somePromise().catch(function (err) {
  //Exception handling
});

somePromise().then(null, function (err) {
  //Exception handling
});

However, if you don’t just handle exceptions, the following two situations are different

somePromise().then(function () {
  return otherPromise();
}).catch(function (err) {
  //Exception handling
});

somePromise().then(function () {
  return otherPromise();
}, function (err) {
  //Exception handling
});

Not clear enough? So what if that’s the case? IfThe first callback function throws an errorWhat will happen?

somePromise().then(function () {
  Throw new error ('wrong here ');
}).catch(function (err) {
  console.log(err)
  //This is wrong!:)
});

somePromise().then(
function () {
  Throw new error ('wrong here ');
}, 
function (err) {
  console.log(err)
  //Unknown:(
  //There is no catch to the error above
});

The conclusion is that when usingthen(resolveHandler, rejectHandler)rejectHandlerWill not be captured inresolveHandlerError thrown in!

It’s finished. OK, what’s the use of this?

It seems that this notice does not affect the normal use

Because my personal habit is to use the catch () method instead of the second parameter of the then method

So, the question is, how to use it correctlycatchWhat about it? In fact, I don’t have a good idea,Hope to give adviceThrow two bricks at random

// 1
somePromise()
    .then(resolveHandler)
    //This catch will handle the exception of somepromise or resolvehandler
    .catch(rejectHandler) 
    .then(otherResolveHandler)
    //And this catch only handles the resolvehandler exception
    .catch(otherRejectHandler)
    
// 2
somePromise()
    .then(resolveHandler)
    .then(otherResolveHandler)
    //As for this catch, it will handle the exceptions of somepromise, resolvehandler and otherresolvehandler
    .catch(rejectHandler)
    
// 3 
somePromise()
    .catch(console.log.bind(console))
    //Equivalent to
    .catch(function(err){
        console.log(err)
    })

Ha ha ha, I’d better think about promise again. I’ll make it clear and add it. Thank you again@n ͛ i ͛ g ͛ h ͛ t ͛ i ͛ r ͛ e ͛ greatlyThe king of Qin was assassinated by Jingke

Process control: JQ deferred and ES6 promise use novice to pit!

Write very rough, there are mistakes in the hope of a lot of advice!!

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]