Talk about the history of promise in Q.js

Source: Internet
Author: User

Reprinted from: http://segmentfault.com/a/1190000002591145

Promise Core Notes

Promise specifications, please Baidu Search prommise/a+ specifications, promise Core is there is a then method. In related terms, promise refers to having a then

method, and the method can trigger the object or function of a particular behavior.

Start: Understand promise in this way

Recall what the promise solved? Callback. For example: the function DoMission1 () represents the first thing, and now we want to do it after this thing is done

One thing DoMisson2 (), what should be done?

Let's look at our common callback patterns. DoMission1 () said, "If you want to do this, give me DoMission2 () and I'll call you after the end." "So it would be:

DoMission1 (DoMission2);

What about the Promise model? You said to DoMission1 (): "No, control is in my place." You should change a bit, you first return a special thing to me, and then

I came here to arrange the next thing. "This particular thing is promise, and this becomes the case:

DoMission1 (). then (DoMission2);

As can be seen, promise will callback mode of the master-slave relationship for a position (turn over to do the master!) ), the process relationship of multiple events can be so focused on the trunk to the top (not

Dispersed within the various event functions).

Well, how do you do such a conversion? From the simplest case, assume that the code for DoMission1 () is:

function DoMission1 (callback) {     var value = 1;     

Well, it can change a bit and become like this:

function DoMission1 () {     var value = 1,                  = {             function(callback) { C10/>callback (value);             }         };                   return Self ;}

This completes the conversion. Although not actually useful conversion, but here, actually has touched the promise most important realization point

Promise converts the return value to an object with the then method.

Advanced: Q Design Distance

Start with the def.

 vardef =function(){     varPending =[], value, self={resolve:function(_value) {value=_value;  for(vari = 0, len = pending.length; i < Len; i++ ){                     varcallback =pending[i];                 callback (value); } Pending=undefined; }, then:function(){                 if(Pending) {Pending.push (callback); }Else{callback (value);              }             }         }; returnSelf ;}; 

As you can see from this source, running Def () will get an object that contains the resolve and then methods. Please recall the deferred of jquery (also

Resolve and then), these two methods will be approximate effects. Then it will refer to the status of the pending, and if it is a wait state, save the callback (push),

Otherwise call the callback immediately. Resolve will be sure that this promise, while updating the value, runs all the saved callbacks. For example:

var function () {    var result = def ();         function () {        1 );    };              return  function(value) {    console.log (value);    });

In order to resolve multiple calls to resolve, you can give a status judgement, the code is modified as follows:

 vardef =function(){     varPending =[], value, self={resolve:function(_value) {if(Pending) {value=_value;  for(vari = 0, len = pending.length; i < Len; i++ ){                         varcallback =pending[i];                     callback (value); } Pending=undefined; }}, then:function(callback) {if(Pending) {Pending.push (callback); }Else{callback (value);              }             }         }; returnSelf ;};
Separating Der and Promise

In the previous implementation, the Def-generated object has both the then method and the Resolve method. By definition, promise only cares about the then method, as for

Triggering promise to change the state of resolve is another matter. So, Q will then have the promise of the then method, and the Def with resolve

Separate from each other and used independently. This is like a clear delineation of their respective responsibilities, leaving only a certain amount of authority, which makes the code logic clearer and easier to adjust.

See Desige/q3.js:

varIspromise =function(value) {returnValue &&typeofValue.then = = = "function";};vardef =function(){    varPending =[], value, self={resolve:function(_value) {if((Pending) {value=_value;  for(vari = 0, len = pending.length; i < Len; i++ ){                        varcallback =pending[i];                    callback (value); } Pending=undefined; }}, Promise: {then:function(){                    if(Pending) {Pending.push (callback); }Else{callback (value);                }                }            }        }; returnself.promise;};
Implement Promise Cascade

The next step will be a very important one. To the front of the Q3, the implementation of the promise are not cascading. But the promise you are familiar with should support this syntax:

Promise.then (STEP1). then (STEP2);

The above process can be understood as promise will be able to create new promise, and is taken from the old promise value (value in the preceding code). To achieve Then

Cascade, there are a few things you need to do:

The 1,then method must return promise;

2, the returned promise must set its own value with the return result of the callback passed to the then method;

3, the callback passed to the then method must return a promise or value;

Design/q4.js, in order to achieve this, a new tool function ref:

var function (value) {    iftypeof Value.then = = = = "function" ) {        return  value;    }         return {        function(callback) {            var _value = callback (value);             return  ref (_value);};    };

If the ref function parameter value is a non-promise object, then value is passed to the next callback function, wrapped as a promise object.

Ref ("Step1"). Then (function(value) {    //  "Step1"    return  ;}). Then (function(value) {    //  });

You can see how value is passed, and the promise Cascade needs to do the same.

varThenable =function(value) {if(Value &&typeofValue.then = = = "function" ){        returnvalue; }        return{then:function(callback) {var_value =callback (value); returnthenable (_value); }    };};vardefer =function(){    varPending =[], value, self={resolve:function(_value) {if(pending) {//values wrapped in a promiseValue =thenable (_value);  for(i = 0, len = pending.length; i < Len; i++ ){                        varcallback =pending[i]; Value.then (callback); //The called instead.} pending=undefined; }}, Promise: {then:function(_callback) {varresult =defer (); varcallback =function(value) {var_value =_callback (value);                    Result.resolve (_value);                                        }; if(Pending) {Pending.push (callback); }Else{Value.then (callback); }                                        returnresult.promise;                }            }        }; returnSelf ;};

1, a new promise object will be generated each time.

2, the incoming _callback will be packaged into the callback function, the newly generated defer object placed in the Resolve method, this is in the old defer object resolve,

By defer the promise-hung callback function, the new defer object can continue to resolve;

Here is the test code:

var deffered = defer ();d effered.promise.then (function(value) {        Console.log ( value);         return 2;}). Then (function(value) {    function() {    11000);
Add error handling

The then method of promise should be able to contain two parameters, namely, the processing function of affirmative and negation states (Onfulfilled and onrejected). Front

The promise that we achieve can only be turned into a positive state, so the next step is to add the negative state part.

Note that the two parameters of the then method of the promise are optional parameters. Design/q6.js added the tool function reject to help implement promise

State of negation.

var function (reason) {        return  {            function(callback, Errback) {                  return  ref (Errback (reason));};        };

Next, look at the rest of the design/q6.js:

vardefer =function(){    varPending =[], value, self={resolve:function(_value) {if(Pending) {value=ref (_VALUE);  for(vari = 0, len = pending.length; i < Len; i++) {value.then.apply (value, pending[i]); } Pending=undefined; }}, Promise: {then:function(_callback, _errback) {varresult =defer (); _callback= _callback | |Functioin (value) {returnvalue;                                        }; _errback= _errback | |function(reason) {returnreject (reason);                                        }; varcallback =function(value) {Result.resolve (_callback (value));                                        }; varErrback =function(value) {Result.resolve (_callback (value));                                        }; if(Pending) {Pending.push ([callback, Errback]); }Else{Value.then (callback, Errback); }                                        returnresult.promise;                }            }        }; returnSelf ;};

Talk about the history of promise in Q.js

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.