Simplified version of handwritten promise ideas

Constructorconstructor(executor)

  • Receives an executor function executorthat accepts two arguments: resolveand reject.
  • The initial state statusis set to 'pending', indicating that the Promise has not yet been resolved.
  • valueProperties are used to store the value passed when a Promise is fulfilled or rejected.
  • onFulfilledCallbacksand onRejectedCallbacksare used to store callback functions registered in .thenor .catchthat are executed when a Promise is resolved or rejected.

resolveand rejectfunction

  • resolve(value)The and reject(reason)function changes the state of Promise and sets it value, and then executes the corresponding callback function list.
  • These two functions check whether the current state is 'pending'to prevent the Promise state from being changed multiple times.
  • When resolveis called, the state becomes 'fulfilled', and all onFulfilledCallbacksfunctions in are executed asynchronously.
  • When rejectis called, the state becomes 'rejected', and all onRejectedCallbacksfunctions in are executed asynchronously.

then(onFulfilled, onRejected)

  • thenThe method receives two parameters: onFulfilledand onRejected, which are callback functions when the Promise is resolved or rejected respectively.
  • Default functions are provided to ensure that thenmethods properly return a new Promise even if these functions are not passed.
  • Based on the current Promise status, decide to execute the callback immediately or add the callback to the corresponding callback list.
  • Returns a new SimplePromiseobject, allowing chaining of calls.

Chained calls and asynchronous execution

  • thenand methods support chaining of calls catchby returning a new instance.SimplePromise
  • Asynchronous execution of callbacks is setTimeoutimplemented by wrapping the callback function in to ensure that the callback is always executed asynchronously after the function execution stack is cleared.

Error handling

  • Catch the exception in executorthe execution or callback function execution and pass the exception to rejectthe function as the reason for rejection.

catch(onRejected)

  • catchMethod is thensyntactic sugar for method and only handles rejection cases.

This SimplePromiseclass implements thenand catch, but does not implement Promiseall the functions of , such as Promise.allPromise.racePromise.resolvePromise.rejectand other static methods. In addition, this implementation does not handle some edge cases, such as handling a Promise that returns itself in a chained call, or thenreturning another Promise in a chain. These are complexities that need to be considered in a complete, Promises/A+ compliant implementation.

class  SimplePromise {
constructor ( executor ) {
// The initialization status is 'pending'
this . status = 'pending' ;
// value is used to save the return value of success or failure
this . value = null ;
// Save the processing of success and failure. Function
this . onFulfilledCallbacks = [];
this . onRejectedCallbacks = [];

// Success handling function
const resolve = ( value ) => {
if ( this . status === 'pending' ) {
this . status = 'fulfilled' ;
this . value = value;
this . onFulfilledCallbacks . forEach ( ( callback ) => callback (value));
}
};

// Failure handling function
const reject = ( reason ) => {
if ( this . status === 'pending' ) {
this . status = 'rejected' ;
this . value = reason;
this . onRejectedCallbacks . forEach ( ( callback ) => callback (reason));
}
};

// Execute the executor immediately and pass in resolve and reject
try {
executor (resolve, reject);
} catch (error) {
reject (error);
}
}

then ( onFulfilled, onRejected ) {
// If onFulfilled is not a function, provide a default function and return value
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : ( value ) => value;
// If onRejected is not a function, provide a Default function, throws an error
onRejected = typeof onRejected === 'function' ? onRejected : ( reason ) => { throw reason; };

// Return a new Promise
return new SimplePromise ( ( resolve, reject ) => {
// If the status has been determined to be fulfilled, execute onFulfilled immediately
if ( this . status === 'fulfilled' ) {
setTimeout ( () => {
try {
const result = onFulfilled ( this . value );
resolve (result);
} catch (error) {
reject (error);
}
});
}

// If the status has been determined to be rejected, execute onRejected immediately
if ( this . status === 'rejected' ) {
setTimeout ( () => {
try {
const result = onRejected ( this . value );
reject (result);
} catch (error) {
reject (error);
}
});
}

// If the status is still pending, put onFulfilled and onRejected into the corresponding processing array
if ( this . status === 'pending' ) {
this . onFulfilledCallbacks . push ( ( value ) => {
try {
const result = onFulfilled (value);
resolve (result);
} catch (error) {
reject (error);
}
});

this . onRejectedCallbacks . push ( ( reason ) => {
try {
const result = onRejected (reason);
reject (result);
} catch (error) {
reject (error);
}
});
}
});
}

catch (onRejected) {
// catch is a syntax sugar for then, which only provides onRejected processing function
return this . then ( null , onRejected);
}
}

// Example 1: resolve
const promise1 = new SimplePromise ( ( resolve, reject ) => {
resolve ( 'test resolve' )
})
promise1. then ( ( res ) => {
console . log (res)
}). catch ( ( err ) => {
console . log (err)
})
// Example 2: rejected
const promise2 = new SimplePromise ( ( resolve, reject ) => {
reject ( 'test reject' )
})
promise2. then ( res => {
console . log (res)
}). catch ( err => {
console . log (err)
})
// Example 3 Asynchronous operation
const promise3 = new SimplePromise ( ( resolve, reject ) => {
setTimeout ( () => {
resolve ( 'test after timeout' )
}, 1000 );
})
promise3. then ( res => {
console . log (res)
}). catch ( err => {
console . log (err)
})
// Example 4: Asynchronous call
const promise4 = new SimplePromise ( ( resolve, reject ) => {
resolve ( 1 )
})
promise4. then ( res => {
console . log (res)
return res + 1
}). then ( res => {
console . log (res)
return res + 1
}). then ( res => {
console . log ( res)
}). catch ( err => {
console . log (err)
})