Original address: http://www.cnblogs.com/dojo-lzz/p/4340897.html
Resolve callback functions nested too deep, parallel logic must be executed serially, a promise represents the end result of an asynchronous operation, the main way to interact with promise is to register the callback function with his then () method to receive the final result value of promise
Promise related protocols are Promisea and promisea+.
Defines a class of promise
Define a property queue, initialize an empty array []
Define property value, initialize NULL
Define the attribute state status, initialize the "Pending" (default value)
Defines the Member Method Getqueue (), which returns the property of the queue
Define member Method GetStatus (), Return property status
Define member Method SetStatus (), set state, pass parameter: Status,value
Judge the status as fulfilled or rejected,
Set the Status property This.status=status
Set the Value property This.value=value | | Null if the value is not passed as null
Defining a Frozen variable freezeobject
Define member Method Isfulfilled () to determine whether the current state is (completed)
Define member Method Isrejected () to determine whether the current state is (failed)
Define member Method Ispending (), judging the current state the master is (waiting)
Define member method then (), pass parameter: onfulfilled successful callback, Onrejected failed callback
Define object Handler object, attribute fulfilled,rejected two callback functions
Defines the deferred property of the handler object, deferred object
Determines whether the current state waits, if it is waiting for the handler object to be plugged into the queue array
If it is not a wait state, call the Utils object's procedure () method, parameter: status,
Returns the Handler.deferred.promise object
Defines a class of deferred
Define attribute Promise, Initialize promise Object
Defining member methods Resolve (), passing parameters: result results
Determine the state of the Promise object is waiting, return directly
Call the Getqueue () method of the Promise object to get the queue array
Loop array
Todo invokes the tool class Utils. Procedure () method, Parameter: "Fulfilled", element, err information
Call the SetStatus () method of the Promise object, set the state, parameter: ' fulfilled ', result
Defining member methods Reject, passing parameters: Err error message
Determine the state of the Promise object is waiting, return directly
Call the Getqueue () method of the Promise object to get the queue array
Loop array
Todo, call the tool class Utils. Procedure () method, Parameter: "Rejected", element, err information
Call the SetStatus () method of the Promise object, set the state, parameter: ' fulfilled ', result
Defining tool Classes Utils , using an anonymous function to execute immediately, to get an object
Returns an object that has a method procedure ()
Define the procedure () method, pass parameters: type status, handler processor array, result
Get to handler function Func, in Handler[type]
Here I see a faint ...
How to use:
Define a function Ajax, pass parameters: URL path
Get deferred object, new out
The code for the AJAX request data, in the callback method that returns the data
If successful, call the deferred object's resolve () method, parameter: The returned data
If the Reject () method that calls the deferred object fails, the parameter: the returned data
Returns the Deferred.promise object
Call the Ajax () method to get the Promise object, parameters: URL,
Call the then () method of the Promise object, parameter: anonymous function
Call the Ajax () method, get to the Promise object, return this object
Forming chained calls
JS section:
<script>//Promise Code section (I choose Dog straps)Promise =function() { This. Queue = []; This. Value =NULL; This. Status = ' pending ';//pending fulfilled rejected}; Promise.prototype.getQueue=function() { return This. Queue;}; Promise.prototype.getStatus=function() { return This. status;}; Promise.prototype.setStatus=function(S, value) {if(s = = = ' fulfilled ' | | s = = = ' rejected ')) { This. Status =s; This. Value = value | |NULL; This. Queue = []; varFreezeobject = Object.freeze | |function(){}; Freezeobject ( This);//The state of promise is irreversible.}Else { Throw NewError ({message:"Doesn ' t support status:" +s}); }}; Promise.prototype.isFulfilled=function() { return This. Status = = = ' fulfilled ';}; Promise.prototype.isRejected=function() { return This. Status = = = ' Rejected ';} Promise.prototype.isPending=function() { return This. Status = = = ' Pending ';} Promise.prototype.then=function(onfulfilled, onrejected) {varHandler = { ' Fulfilled ': onfulfilled,' Rejected ': onrejected}; Handler.deferred=NewDeferred (); if(! This. Ispending ()) {//This allows you to add a callback after changing the Promise State firstUtils.procedure ( This. Status, Handler, This. Value); } Else { This. Queue.push (handler);//Then May is called multiple times on the same promise; specification 2.2.6 } returnHandler.deferred.promise;//Then must return a promise; specification 2.2.7};varUtils = (function(){ varMakesignaler =function(deferred, type) {return function(Result) {Transition (deferred, type, result); } }; varProcedure =function(type, handler, result) {varFunc =Handler[type]; vardef =handler.deferred; if(func) {Try { varNewresult =func (Result); if(Newresult &&typeofNewresult.then = = = ' function ') {//thenable //in this way, closures are prone to memory leaks, and we solve them through higher-order functions. //Newresult.then (function (data) { //def.resolve (data); //}, function (err) { //Def.reject (err); // }); //promisea+ Specification, X represents newresult,promise for Def.promise //If X is a promise, adopt it State [3.4]: //If X is pending, promise must remain pending until X is fulfilled or rejected. //If/when X is fulfilled, fulfill promise with the same value. //If/when X is rejected, reject promise with the same reason.Newresult.then (Makesignaler (Def, ' fulfilled '), Makesignaler (Def, ' rejected '));//The essence here is the use of asynchronous closures}Else{Transition (Def, type, newresult); } } Catch(ERR) {transition (Def,' Rejected ', err); } } Else{Transition (Def, type, result); } }; varTransition =function(deferred, type, result) {if(Type = = = ' fulfilled ')) {deferred.resolve (result); } Else if(Type = = = ' rejected ')) {deferred.reject (result); } Else if(Type!== ' pending ') { Throw NewError ({' Message ': ' doesn ' t support type: ' +type}); } }; return { ' Procedure ': Procedure}}) ();D eferred=function() { This. Promise =NewPromise ();};D Eferred.prototype.resolve=function(Result) {if(! This. promise.ispending ()) { return; } varQueue = This. Promise.getqueue (); for(vari = 0, len = queue.length; i < Len; i++) {utils.procedure (' Fulfilled ', queue[i], result); } This. Promise.setstatus (' fulfilled ', result),};D Eferred.prototype.reject=function(err) {if(! This. promise.ispending ()) { return; } varQueue = This. Promise.getqueue (); for(vari = 0, len = queue.length; i < Len; i++) {utils.procedure (' Rejected ', Queue[i], err); } This. Promise.setstatus (' Rejected ', err);}/***************************** above can not understand, split line ************************************///Test SectionAjax =function(URL) {vardef =NewDeferred (); varXHR =NewXMLHttpRequest (); Xhr.onreadystatechange=function() { if(Xhr.readystate = = 4) { if((Xhr.status >=200 && xhr.status <) | | xhr.status = = 304) {def.resolve (xhr.responsetext)}Else{//simplifies Ajax and does not provide error callbacksDef.reject (NewError ({message:xhr.status})); } } }; Xhr.open (' Get ', url,true); Xhr.send (NULL); returnDef.promise;} Ajax (' Test.php?act=1 '). Then (function(data1) {console.log (data1);//Handling Data1 returnAjax (' test.php?act=2 ');}). Then (function(data2) {console.log (data2);//Handling Data2 returnAjax (' test.php?act=3 ');}, function(Err) {console.error (err);}). Then (function(data3) {console.log (DATA3); Alert (' Success ');}, function(Err) {console.error (err);});</script>
Php:
<?PHPif($_get[' Act ']==1){ EchoJson_encode (Array("Code" =>200));}Else if($_get[' Act ']==2){ EchoJson_encode (Array("Code" =>300));}Else if($_get[' Act ']==3){ EchoJson_encode (Array("Code" =>400));}
[JavaScript] Promise Simple Learning to use