Handwritten Promise
1 define the overall structure
class Promise{ /* Promise Constructor executor: Internally synchronously executed functions (resolve, reject) = > {} */ constructor(executor){ } /* Specify the success / failure callback function for promise The return value of the function is a new promise object */ then(onResolved, onRejected){ } /* Specify the failed callback function for promise Is the syntax of then(null, onRejected) */ catch(onRejected){ } /* Returns a promise object with a success value specified */ Promise.resolve = function (value){ } /* Returns a promise object specifying the failure reason */ static reject(reason){ } /* all Implementation of the method: return a promise. Only when all the promises in the promises are successful will it succeed finally. As long as there is a failure, it will fail directly */ static all(promises){ } /* race Method implementation: once a promise is resolved or rejected, the returned promise will be the current state. Whoever changes the state first will return to who */ static race(promises){ } }
2 implementation of promise constructor
constructor(executor){ //Add attribute this.PromiseState = 'pending'; this.PromiseResult = null; //Declare properties this.callbacks = []; //Save the value of this of the instance object const self = this;// self _this that //resolve function function resolve(data){ //Judgment state if(self.PromiseState !== 'pending') return; //1. Modify the object's state (promiseState) self.PromiseState = 'fulfilled';// resolved //2. Set the object result value (promiseResult) self.PromiseResult = data; //Call successful callback function setTimeout(() => { self.callbacks.forEach(item => { item.onResolved(data); }); }); } //reject function function reject(data){ //Judgment state if(self.PromiseState !== 'pending') return; //1. Modify the object's state (promiseState) self.PromiseState = 'rejected';// //2. Set the object result value (promiseResult) self.PromiseResult = data; //Failed callback execution setTimeout(() => { self.callbacks.forEach(item => { item.onRejected(data); }); }); } try{ //Synchronously call "actuator function" executor(resolve, reject); }catch(e){ //Modify the promise object status to fail reject(e); } }
3 promise. Implementation of then() / catch()
//then method encapsulation then(onResolved,onRejected){ const self = this; //Determine callback function parameters if(typeof onRejected !== 'function'){ onRejected = reason => { throw reason; } } if(typeof onResolved !== 'function'){ onResolved = value => value; //value => { return value}; } return new Promise((resolve, reject) => { //Encapsulation function function callback(type){ try{ //Get the execution result of the callback function let result = type(self.PromiseResult); //judge if(result instanceof Promise){ //If it is an object of Promise type result.then(v => { resolve(v); }, r=>{ reject(r); }) }else{ //The object status of the result is success resolve(result); } }catch(e){ reject(e); } } //Call the callback function PromiseState if(this.PromiseState === 'fulfilled'){ setTimeout(() => { callback(onResolved); }); } if(this.PromiseState === 'rejected'){ setTimeout(() => { callback(onRejected); }); } //Determine pending status if(this.PromiseState === 'pending'){ //Save callback function this.callbacks.push({ onResolved: function(){ callback(onResolved); }, onRejected: function(){ callback(onRejected); } }); } }) } //catch method catch(onRejected){ return this.then(undefined, onRejected); }
4 Promise. Implementation of resolve() / reject()
//Add resolve method static resolve(value){ //Return promise object return new Promise((resolve, reject) => { if(value instanceof Promise){ value.then(v=>{ resolve(v); }, r=>{ reject(r); }) }else{ //The status is set to success resolve(value); } }); } //Add reject method static reject(reason){ return new Promise((resolve, reject)=>{ reject(reason); }); }
5 Promise. Implementation of all / race()
//Add all method static all(promises){ //The returned result is promise object return new Promise((resolve, reject) => { //Declare variable let count = 0; let arr = []; //ergodic for(let i=0;i<promises.length;i++){ // promises[i].then(v => { //Know that the status of the object is successful //Each promise object succeeded count++; //Store the successful result of the current promise object into the array arr[i] = v; //judge if(count === promises.length){ //modify state resolve(arr); } }, r => { reject(r); }); } }); } //Add race method static race (promises){ return new Promise((resolve, reject) => { for(let i=0;i<promises.length;i++){ promises[i].then(v => { //Modify the status of the returned object to success resolve(v); },r=>{ //Modify the status of the returned object to "failed" reject(r); }) } }); }
Class 6 encapsulation
class encapsulation: in js classes, there are three methods: constructor construction method, static method and ordinary method.
"constructor construction method"
1. Concept
Class is used to build objects, and the constructor constructor constructor is used to build object instances.
2. Usage
When using the new keyword to generate an object, the constructor method will be executed, and the final return result is the generated object instance.
When a class does not have a constructor method, it will automatically generate an empty constructor method, and the return result is empty.
When instantiating an object with the new keyword, the parameters passed in will be passed in as the parameters of the constructor constructor.
class Point { constructor(name) { console.log('Instantiate objects:'+ name); } } new Point('testObj'); //Instantiate objects:testObj
"Common method"
1. Concept
The ordinary method of class can be regarded as another writing method of constructor, which is equivalent to defining the method on the prototype attribute of class.
2. Usage
(1). This method is used on the object instantiated by this class
class Point { toString() { // ... } } let obj = new Point(); obj.toString();
(2). This method is called directly through the prototype of the class
class Point { toString() { // ... } } Point.prototype.toString();
(3). By subclass__ proto__ call
class Foo { commonMethod() { return 'hello'; } } class Bar extends Foo { } Bar.__proto__.prototype.commonMethod();
"Static method"
1. Concept
Class is equivalent to the prototype of an instance. All methods defined in the class will be inherited by the instance. If you add the static keyword before a method, it means that the method * * will not be inherited by the instance, but will be called directly through the class (calling through the class means calling * * outside the class), which is called "static method".
2. Usage
Static methods can only be called on the current class and cannot be called by the instance object of the class. A static method of a parent class can be inherited by a child class.
Therefore, there are three ways for static methods to be called (all three methods are used in the following code, please read patiently):
- called directly by the parent class
Subclass is called after inheriting the parent class.
- subclasses are called through super objects
class Foo { static classMethod() { return 'hello'; } } Foo.classMethod(); //hello class Bar extends Foo { } class Cla extends Foo { return super.classMethod(); //hello } Bar.classMethod(); //hello
contrast | Static method | Common method | Construction method |
---|---|---|---|
keyword | static | nothing | constructor |
Usage scenario | Declares a method that is used only by the current class or subclasses of the current class | Create methods that can be called directly by instantiated objects | The method executed when instantiating an object through this class with the new keyword |
Use object | Current class or subclass of current class | An object generated by instantiation of the class or a subclass of the class | The class itself |
Call method | 1. Direct call of parent class The 2. subclass calls after inheriting the parent class. 3. Subclasses are called through super objects | 1. Object calls generated through instances of this class and its subclasses 2. This class is called through prototype 3. The subclass of this class is passed__ proto__ Implicit prototype chain call | 1. Called when this class instantiates an object 2. Subclasses of this class are called with the super keyword |
Note: in class, its static attribute and common attribute can have the same name. However, duplicate names are not recommended, and the demo will not be given here
Sample demo
class Person{ constructor() { // Everything added to this will exist on different instances this.locate = () => console.log('instance',this); } // Defined on the prototype object of the class locate(){ console.log('prototype', this); } // Defined on the class itself static locate(){ console.log('class',this); } } let p = new Person(); p.locate(); // instance, Person() Person.prototype.locate(); // prototype. {constructor: ... } Person.locate(); // class, class Person { }