Promise super super simple summary:
I always felt promise was mysterious before. Today I read Ruan Yifeng's es6 carefully and inquired about the promise principle. Finally I understand how promise is so 6.
Introduction:
Promise objects are used for deferred and asynchronous computing. A Promise object represents an operation that is not yet completed but is expected to be completed in the future. The Promise object is a proxy for a return value that is not necessarily known when the promise object is created. It allows you to specify a handler for the success or failure of an asynchronous operation. This allows an asynchronous method to return values like a synchronous method: the asynchronous method returns a promise object containing the original return value instead of the original return value.
What problems have been solved and how to use them?
//A simple example executes an animation A and then another animation B.
setTimeout(function(){
//A Animation
console.log('A');
setTimeout(function() {
//B Animation
console.log('B');
},300)
},300);
//There are only two animations, and if there are more, you'll see a bunch of function indentations.
(1) Browser implementations can be run on Promise-enabled versions
var p = new Promise(function(resolve, reject){
setTimeout(function(){
//A Animation
console.log('A');
resolve();
},300);
});
p.then(function(){
setTimeout(function() {
//B Animation
console.log('B');
},300);
});
(2) Another way of writing (jQuery version)
var deferred = $.Deferred();
setTimeout(function(){
//A Animation
console.log('A');
deferred.resolve();
},300);
deferred.done(function() {
setTimeout(function() {
//B Animation
console.log('B');
},300)
});
Promises make code easier to maintain, writing asynchronous code just like writing synchronous code.
promise principle
In fact, promise is three states. Using the observer mode, only the event handler of the corresponding state is registered through a specific writing mode, then the state is updated and the registered handler is invoked.
This particular way is then, done, fail, always... For example, update status is resolution and reject method.
The following simple implementation:
/**
/**
* [3 Species status]
* @type {String}
*/
var PENDING = "pending";
var RESOLVED = "resolved";
var REJECTED = "rejected";
/**
* [Promise Class implementation]
* The constructor passes in an fn with two parameters, resolution: successful callback; reject: failed callback;
* state: State Storage
* doneList: List of Successful Processing Functions
* failList: List of Failure Handling Functions
* done: Registered Success Processing Function
* fail: Register Failure Handler
* then: Register both success and failure handlers
* always: A process that registers to success or failure calls
* resolve: Update the state to RESOLVED and execute the successful processing queue
* reject: Update the state to REJECTED and execute the failed processing queue
*/
var Promise2 = (function() {
var noop = function() {}
function Promise(fn) {
this.state = PENDING;
this.doneList = [];
this.failList = [];
this.fn = fn;
this.fn(this.resolve.bind(this), this.reject.bind(this)) //Execute the first parameter of the constructor immediately
}
var p = {
done: function(cb) {
if (typeof cb == "function")
this.doneList.push(cb)
return this;
},
fail: function(cb) {
if (typeof cb == "function")
this.failList.push(cb);
return this;
},
then: function(success, fail) {
this.done(success || noop).fail(fail || noop)
return this;
},
always: function(cb) {
this.done(cb).fail(cb)
return this;
},
resolve: function() {
this.state = RESOLVED;
var lists = this.doneList;
for (var i = 0; i < lists.length;) {
lists[i].apply(this, arguments);
lists.shift();
}
return this;
},
reject: function() {
this.state = REJECTED;
var lists = this.failList;
for (var i = 0; i < lists.length;) {
lists[0].apply(this, arguments);
lists.shift();
}
return this;
}
}
for (var k in p) {
Promise.prototype[k] = p[k]
}
return Promise;
})();
//Test code
var p1 = new Promise2(function(resolve,reject){
setTimeout(resolve,2000);
console.log('p1',new Date);
});
p1.then(function(){
console.log("end",new Date);
}).always(function(){
console.log('always',new Date);
});
Using the observer mode, only need to register the event handler of the corresponding state through a specific writing mode, then update the state and call the registered handler.
Interpretation: When we call new Promise(fn), the first parameter FN is executed immediately. In the above case, the callback function corresponding to then(done,fail) is added to either doneList or failList, and the corresponding parameters in always are added to both doneList and failList. When the asynchronous code is executed, the resolve method is called. At this time, the status of promise is changed to resolve, and the callback function in doneList is executed. If the execution fails, the fail method is called, which changes the status of promise to rejected and executes the callback function in the failList.