Solve that the callback function is too deep, and parallel logic must be executed serially. A Promise represents the final result of an asynchronous operation. The main way to interact with Promise is to register the callback function through its then() method to receive the final result value of the Promise.
Promise-related protocols include PromiseA and PromiseA+
Define a class Promise
Define the attribute queue queue, initialize the empty array[]
Define the property value value, initialize null
Define the status status of the property and initialize "pending" (default value)
Define member method getQueue(), return attribute queue
Define member method getStatus(), return the attribute status
Define member method setStatus(), set status, pass parameters: status, value
Determine that status is fulfilled or rejected,
Set status property this.status=status
Set the value property this.value=value || null , if you do not pass the value, it is null
Define the freeze 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(), determine the current status master is (waiting)
Define member method then(), pass parameters: onFulfilled successful callback, onRejected failed callback
Define two callback functions: handler object, attribute fulfilled, rejected
Define the deferred property of the handler object, the Deferred object
Determine whether the current state is waiting. If it is waiting, put the handler object into the queue queue array
If it is not a waiting state, call the procedure() method of the Utils object, parameter: status,
Return handler.deferred.promise object
Define a class Deferred
Define the attribute promise and initialize the Promise object
Define the member method resolve(), pass the parameter: result result
Determine the status of the Promise object as waiting and return directly
Call the getQueue() method of the Promise object to get the queue array
Loop array
//todo calls the tool class Utils. procedure() method, parameters: "fulfilled", element, err information
Call the setStatus() method of the Promise object, set the status, parameters: 'fulfilled', result
Define member method reject, pass parameter: err error message
Determine the status of the Promise object as waiting and 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, parameters: "rejected", element, err information
Call the setStatus() method of the Promise object, set the status, parameters: 'fulfilled', result
Define the tool class Utils, execute it immediately using anonymous functions, and get an object
Returns the object, there is a method procedure() in the object
Define the procedure() method, pass parameters: type state type, handler processor array, result result
Get the processing function func, in handler[type]
I was dizzy when I got here. . .
How to use:
Define a function ajax, pass the parameter: url path
Get the Deferred object and come out new
Ajax's code to request data, in the callback method that returns data
If the resolve() method of the Deferred object is successfully called, parameter: return data
If the reject() method of the Deferred object is called failed, parameter: returned data
Return the Deferred.promise object
Call ajax() method to get the promise object, parameter: url,
Call the then() method of the promise object, parameters: anonymous function
Call the ajax() method to get the promise object and return this object
Form a chain call
js part:
<script>//Promise code part (I chose the dog belt) 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 = []; var freezeObject = Object.freeze || function(){}; freezeObject(this);// The state of promise is irreversible} else { throw new Error({ 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) { var handler = { 'fulfilled': onFulfilled, 'rejected': onRejected }; handler.deferred = new Deferred(); if (!this.isPending()) {//This is allowed to change the promise status first and then add callbacks utils.procedure(this.status, handler, this.value); } else { this.queue.push(handler);//then may be called multiple times on the same promise;Specification 2.2.6 } return handler.deferred.promise;//then must return a promise;Specification 2.2.7};var utils = (function(){ var makeSignaler = function(deferred, type) { return function(result) { transition(deferred, type, result); } }; var procedure = function(type, handler, result) { var func = handler[type]; var def = handler.deferred; if (func) { try { var newResult = func(result); if (newResult && typeof newResult.then === 'function') {//thenable // This writing method has closures and can easily cause memory leakage. We solve it through higher-order functions // newResult.then(function(data) { // def.resolve(data); // }, function(err) { // def.reject(err); // }); // PromiseA+ specification, x represents newResult, promise represents def.promise // If x is a promise, adopt its 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 to use asynchronous closure} else { transition(def, type, newResult); } } catch(err) { transition(def, 'rejected', err); } } else { transition(def, type, result); } }; var transition = function(deferred, type, result) { if (type === 'fulfilled') { deferred.resolve(result); } else if (type === 'rejected') { deferred.reject(result); } else if (type !== 'pending') { throw new Error({ 'message': "doesn't support type: " + type }); } }; return { 'procedure': procedure }})();Deferred = function() { this.promise = new Promise();};Deferred.prototype.resolve = function(result) { if (!this.promise.isPending()) { return; } var queue = this.promise.getQueue(); for (var i = 0, len = queue.length; i < len; i++) { utils.procedure('fulfilled', queue[i], result); } this.promise.setStatus('fulfilled', result);};Deferred.prototype.reject = function(err) { if (!this.promise.isPending()) { return; } var queue = this.promise.getQueue(); for (var i = 0, len = queue.length; i < len; i++) { utils.procedure('rejected', queue[i], err); } this.promise.setStatus('rejected', err);}/***************************************************************************/// Test part ajax = function(url) { var def = new Deferred(); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) { def.resolve(xhr.responseText) } else {//Simplify ajax, no error callback provided def.reject(new Error({ message: xhr.status })); } } } } }; xhr.open('get', url, true); xhr.send(null); return def.promise;}ajax('test.php?act=1').then(function(data1) { console.log(data1);//handle data1 return ajax('test.php?act=2');}).then(function(data2) { console.log(data2);//handle data2 return ajax('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){ echo json_encode(array("code"=>200));}else if($_GET['act']==2){ echo json_encode(array("code"=>300));}else if($_GET['act']==3){ echo json_encode(array("code"=>400));}The above summary of the simple learning and usage of javascript Promise is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.