Write a Promise
Summarize the step-by-step process of implementing promises
1. Implement resolve and reject functions
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
When // // calls resolve, reject directly,this points to the window, so create a variable that holds the this value of the instance object
const self = this;
/ / 1. Resolve function
function resolve(data){
// Change the state of an object (promiseState)
self.PromiseState = 'fulfilled';
// Set object result value (promiseResult)
self.PromiseResult = data;
}
/ / 2. Reject function
function reject(data){
// Change the state of an object (promiseState)
self.PromiseState = 'rejected'; /// Set object result value (promiseResult)
self.PromiseResult = data;
}
// Call "executor function" synchronously
executor(resolve, reject);
}
// Add the then method
Promise.prototype.then = function(onResolved, onRejected){}Copy the code
2. Throw an error to change the state
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
const self = this;
function resolve(data){
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
}
function reject(data){
self.PromiseState = 'rejected';
self.PromiseResult = data;
}
try{
// Call "executor function" synchronously
executor(resolve, reject);
}catch(e){
// Change the promise object state to "failed"reject(e); }}Promise.prototype.then = function(onResolved, onRejected){}Copy the code
3. The Promise state can be changed only once
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
const self = this;
function resolve(data){
// Determine the status
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
}
function reject(data){
// Determine the status
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';//
self.PromiseResult = data;
}
try
executor(resolve, reject);
}catch(e){ reject(e); }}Promise.prototype.then = function(onResolved, onRejected){}Copy the code
4. The synchronization task then method executes the callback function
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
const self = this;
function resolve(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
}
function reject(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';//
self.PromiseResult = data;
}
try
executor(resolve, reject);
}catch(e){ reject(e); }}// Add the then method
Promise.prototype.then = function(onResolved, onRejected){
// Call the callback function
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult); }}Copy the code
5. The asynchronous task then method performs the callback
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
// Declare attributes
this.callback = {};
const self = this;
function resolve(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
// Call the successful callback function
if(self.callback.onResolved){ self.callback.onResolved(data); }}function reject(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';//
self.PromiseResult = data;
// Perform the callback
if(self.callback.onResolved){ self.callback.onResolved(data); }}try{
executor(resolve, reject);
}catch(e){ reject(e); }}Promise.prototype.then = function(onResolved, onRejected){
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
// Determine pending status
if(this.PromiseState === 'pending') {// Save the callback function
this.callback = {
onResolved: onResolved,
onRejected: onRejected
}
}
}
Copy the code
6. Specify multiple callbacks
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
// Declare attributes
this.callbacks = [];
const self = this;
function resolve(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
// Call the successful callback function
self.callbacks.forEach(item= > {
item.onResolved(data);
});
}
function reject(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = data;
// Execute the failed callback function
self.callbacks.forEach(item= > {
item.onRejected(data);
});
}
try{
executor(resolve, reject);
}catch(e){ reject(e); }}Promise.prototype.then = function(onResolved, onRejected){
if(this.PromiseState === 'fulfilled'){
onResolved(this.PromiseResult);
}
if(this.PromiseState === 'rejected'){
onRejected(this.PromiseResult);
}
// Determine pending status
if(this.PromiseState === 'pending') {// Save the callback function
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected }); }}Copy the code
7. Synchronously modify the Promise state then method to return the result
The result of the then method is a Promise object whose state and value depend on the return value and state of the callback function
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [];
const self = this;
function resolve(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
self.callbacks.forEach(item= > {
item.onResolved(data);
});
}
function reject(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = data;
self.callbacks.forEach(item= > {
item.onRejected(data);
});
}
try{
executor(resolve, reject);
}catch(e){ reject(e); }}Promise.prototype.then = function(onResolved, onRejected){
return new Promise((resolve, reject) = > {
if(this.PromiseState === 'fulfilled') {try{
// Get the result of executing the callback function
let result = onResolved(this.PromiseResult);
// Determine the result type
if(result instanceof Promise) {//result Is an object of type Promise
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{
// Result is not a Promise object
// The object status of the result is "success"resolve(result); }}catch(e){ reject(e); }}if(this.PromiseState === 'rejected') {try{
// Get the result of executing the callback function
let result = onResolved(this.PromiseResult);
// Determine the result type
if(result instanceof Promise) {//result Is an object of type Promise
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{
// Result is not a Promise object
// The object status of the result is "success"resolve(result); }}catch(e){ reject(e); }}// Determine pending status
if(this.PromiseState === 'pending') {// Save the callback function
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected }); }})}Copy the code
8. Asynchronously modify the Promise state then method to return results
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [];
const self = this;
function resolve(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
self.callbacks.forEach(item= > {
item.onResolved(data);
});
}
function reject(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = data;
self.callbacks.forEach(item= > {
item.onRejected(data);
});
}
try{
executor(resolve, reject);
}catch(e){ reject(e); }}Promise.prototype.then = function(onResolved, onRejected){
// Keep the instance object's this
const self = this;
return new Promise((resolve, reject) = > {
if(this.PromiseState === 'fulfilled') {try{
let result = onResolved(this.PromiseResult);
if(result instanceof Promise){
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{ resolve(result); }}catch(e){ reject(e); }}if(this.PromiseState === 'rejected') {try{
// Get the result of executing the callback function
let result = onResolved(this.PromiseResult);
// Determine the result type
if(result instanceof Promise) {//result Is an object of type Promise
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{
// Result is not a Promise object
// The object status of the result is "success"resolve(result); }}catch(e){ reject(e); }}// Determine pending status
if(this.PromiseState === 'pending') {// Save the callback function
this.callbacks.push({
onResolved: function(){
try{
// Execute the success callback
let result = onResolved(self.PromiseResult);
/ / determine
if(result instanceof Promise){
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{ resolve(result); }}catch(e){ reject(e); }},onRejected: function(){
try{
// Execute the success callback
let result = onRejected(self.PromiseResult);
/ / determine
if(result instanceof Promise){
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{ resolve(result); }}catch(e){ reject(e); }}}); }})}Copy the code
9. Optimize the THEN method
// Add the then method
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
return new Promise((resolve, reject) = > {
// Encapsulate the function
function callback(type){
try{
// Get the result of executing the callback function
let result = type(self.PromiseResult);
/ / determine
if(result instanceof Promise) {// If it is an object of type Promise
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'){
callback(onResolved);
}
if(this.PromiseState === 'rejected'){
callback(onRejected);
}
// Determine pending status
if(this.PromiseState === 'pending') {// Save the callback function
this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){ callback(onRejected); }}); }})}Copy the code
10. Catch method and abnormal penetration
// Add the catch method
Promise.prototype.catch = function(onRejected){
return this.then(undefined, onRejected);
}
Copy the code
// Abnormal penetration
Promise.prototype.then = function(onResolved, onRejected){
const self = this;
// Determine the callback parameters
if(typeofonRejected ! = ='function'){
onRejected = reason= > {
throwreason; }}if(typeofonResolved ! = ='function'){
onResolved = value= > value;
}
return new Promise((resolve, reject) = > {
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{ resolve(result); }}catch(e){ reject(e); }}if(this.PromiseState === 'fulfilled'){
callback(onResolved);
}
if(this.PromiseState === 'rejected'){
callback(onRejected);
}
if(this.PromiseState === 'pending') {this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){ callback(onRejected); }}); }})}Copy the code
11. Resolve encapsulation
// Add the resolve method
Promise.resolve = function(value){
// Return the 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 successresolve(value); }}); }Copy the code
12. Reject encapsulation
// Add reject
Promise.reject = function(reason){
return new Promise((resolve, reject) = >{
reject(reason);
});
}
Copy the code
13. Encapsulate the all method
// Add the all method
Promise.all = function(promises){
// Return the result as a Promise object
return new Promise((resolve, reject) = > {
// Declare variables
let count = 0;
let arr = [];
/ / traverse
for(let i=0; i<promises.length; i++){ promises[i].then(v= > {
// The status of the object is success
// Each promise object succeeds
count++;
// Stores the results of the current Promise object's success into an array
arr[i] = v;
/ / determine
if(count === promises.length){
// Change the statusresolve(arr); }},r= >{ reject(r); }); }}); }Copy the code
14. Race method encapsulation
// Add the race method
Promise.race = function(promises){
return new Promise((resolve, reject) = > {
for(let i=0; i<promises.length; i++){ promises[i].then(v= > {
// Change the status of the returned object to "success"
resolve(v);
},r= >{
// Change the state of the returned object to "failed"reject(r); }}})); }Copy the code
15. Asynchronous execution of callbacks
function Promise(executor){
this.PromiseState = 'pending';
this.PromiseResult = null;
this.callbacks = [];
const self = this;
function resolve(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
// Call the successful callback function
setTimeout(() = > {
self.callbacks.forEach(item= > {
item.onResolved(data);
});
});
}
function reject(data){
if(self.PromiseState ! = ='pending') return;
self.PromiseState = 'rejected';//
self.PromiseResult = data;
// Failed callback
setTimeout(() = > {
self.callbacks.forEach(item= > {
item.onRejected(data);
});
});
}
try{
executor(resolve, reject);
}catch(e){ reject(e); }}Promise.prototype.then = function(onResolved, onRejected){
const self = this;
if(typeofonRejected ! = ='function'){
onRejected = reason= > {
throwreason; }}if(typeofonResolved ! = ='function'){
onResolved = value= > value
}
return new Promise((resolve, reject) = > {
function callback(type){
try{
let result = type(self.PromiseResult);
if(result instanceof Promise){
result.then(v= > {
resolve(v);
}, r= >{ reject(r); })}else{ 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 the callback function
this.callbacks.push({
onResolved: function(){
callback(onResolved);
},
onRejected: function(){ callback(onRejected); }}); }})}Copy the code