Teach you to implement a simple promise step by step
- 2021-12-04 17:49:58
- OfStack
step1 Building Framework
1. First of all, we need to place an promise function ontology and add resolve and reject execution functions in it
function Promise(execotor) {}
2. The original promise has two main methods, then and catch, so we need to mount then and catch on the prototype of promise
Promise.prototype.then = function (onResolved, onRejected) {}
Promise.prototype.catch = function (onRejected) {}
3. Mount several common methods for promise resolve, reject, all, race, and so on
resolve: Returns an promise object with a specified result
Promise.resolve = function (value) { }
reject: Method to return failure status
Promise.reject = function (value) { }
all: Returns 1 promise object. This status is successful only if promise returns
Promise.all = function (value) { }
race: Returns an promise object whose state is determined by the first returned object. If any function in this race is executed first, it will directly return the first value, and the others will continue to be executed
Promise.race = function (value) { }
4. Declare mypromise globally
window.Promise = Promise
5. Create a self-executing function to wrap all the above contents in
(function (window) {
})()
step2 populates the built Promise framework
1. Fill in function Promise ()
(1) let self = this Fixed this inside function, which will play a great role later
(2) self. status = 'pending' Adds a base state 'pending' to the Promise function ontology
(3) self. data = undefined Create an data source to store the results returned from resolve
(4) self. callbacks = [] Creates an array to save all callbacks in promise
2. Fill function resolve ()
(1) if (self. status! = = 'pending') {return} Determines whether the status of the current incoming process is pending, if yes, continue the following operation, if not, return directly
There are three states pending, resolved and rejected in promise, all of which are switching variables. If the state is changed from pending to other states, it cannot be changed.
(2) self. status = 'resolved' Change the status of the process to resolved
(3) self. data = value Save value, which will be needed for callbacks in then later
(4) Place the most important execution function section, and if there is an callback function to be executed in sele. data, execute it asynchronously immediately
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(callbackObj => {
callbackObj.onResolved(value)
})
}, 0)
}
3. Fill in function reject ()
(1) Same as resolve function, here abbreviated
4. Fill execotor method
If an error occurs during the execution of the promise body, the error message is captured by the catch, and then the catch will jump to the function to execute an reject separately
try {
execotor(resolve, reject)
} catch (error) {
reject(error)
}
5. Fill in the. then function
First of all, we should distinguish the state of the incoming process. If it is pending state, we should save the callback function. If it is not pending state, we should do something it should do
(1) if (self. status = = = 'pending') If the current state is pending, we will save it
Promise.prototype.then = function (onResolved, onRejected) {}
Promise.prototype.catch = function (onRejected) {}
0
(2) else if (self. status = = = 'resolved') If the status of status is resolved
We'll happily execute it for 1 time
Promise.prototype.then = function (onResolved, onRejected) {}
Promise.prototype.catch = function (onRejected) {}
1
However, there is one state: resolve is not executed, but the state has changed at this time, so we can't execute resolve instead of rejected
Promise.prototype.then = function (onResolved, onRejected) {}
Promise.prototype.catch = function (onRejected) {}
2
After two "simple" steps like how to put an elephant in the refrigerator, we realized a simple Promise
Isn't it very simple? Call your friends around you to try it!