Contents
Constructorconstructor(executor)
- Receives an executor function
executor
that accepts two arguments:resolve
andreject
. - The initial state
status
is set to'pending'
, indicating that the Promise has not yet been resolved. value
Properties are used to store the value passed when a Promise is fulfilled or rejected.onFulfilledCallbacks
andonRejectedCallbacks
are used to store callback functions registered in.then
or.catch
that are executed when a Promise is resolved or rejected.
resolve
and reject
function
resolve(value)
The andreject(reason)
function changes the state of Promise and sets itvalue
, 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
resolve
is called, the state becomes'fulfilled'
, and allonFulfilledCallbacks
functions in are executed asynchronously. - When
reject
is called, the state becomes'rejected'
, and allonRejectedCallbacks
functions in are executed asynchronously.
then(onFulfilled, onRejected)
then
The method receives two parameters:onFulfilled
andonRejected
, which are callback functions when the Promise is resolved or rejected respectively.- Default functions are provided to ensure that
then
methods 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
SimplePromise
object, allowing chaining of calls.
Chained calls and asynchronous execution
then
and methods support chaining of callscatch
by returning a new instance.SimplePromise
- Asynchronous execution of callbacks is
setTimeout
implemented 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
executor
the execution or callback function execution and pass the exception toreject
the function as the reason for rejection.
catch(onRejected)
catch
Method isthen
syntactic sugar for method and only handles rejection cases.
This SimplePromise
class implements then
and catch
, but does not implement Promise
all the functions of , such as Promise.all
, Promise.race
, Promise.resolve
, Promise.reject
and 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 then
returning 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)
})