1、 Create promise constructor infrastructure
-
Get status
Status ='pending 'initialization
'resolved 'obtained
Failed to get 'rejected'
-
Initial data
data = undefined
-
Container function definition failed
onResolved = undefined
onRejected = undefined
-
Define success / failure function resolve / reject
A kind of this.status Change status to obtained / get failed
A kind of this.data Save success / failure data
-
If success / failure, the callback function is defined
Immediate asynchronous success / failure callback
-
If success / failure, the callback function is defined
-
Execute success / failure function resolve / reject
-
If an exception is caught, the result of then retrun promise is failure
Execute reject, pass in error
-
If an exception is caught, the result of then retrun promise is failure
2、 Define the constructor prototype then function, receive success / failure callback onresolved / onrejected, and finally return a new promise instance
-
Define the return promise structure and receive success / failure function parameters. The execution result of return promise is determined by onresolved and onrejected
-
Return promise defines dealwiththenreturn prompt (return promise state processing function) and accepts then’s success / failure callback = = = = > onresolved, onrejected has three results to change the status of return wealth
The execution result is an exception throw. Execute the failure function of return promise and pass in the exception data
The execution result is a promise instance. Whether the return promise calls the success / failure function depends on the promise result of the execution result
If the execution result is not a promise instance, execute the success function of return promise and pass in the execution result
Execute the success / failure callback passed in then and save the return value as result
- Result is an instance of promise
Execute the result instance then method and call back the success / failure function of return promise in its success / failure
- Result is not a promise instance
Execute the return promise function and pass in result
- The result of result execution is exception throw
Catch the exception and execute the return promise failure function. Pass in the error
- Result is an instance of promise
-
-
Return promise defines three ways to process data acquisition status
====>There are three kinds of data acquisition situations, and each state must be asynchronous execution. If the data has been obtained successfully, it means that the data can be directly executed and the onresolved return value can be obtained. If the data acquisition fails, it means that the data can be executed directly and the onrejected return value data is not obtained. It means that onrejected and onresolved cannot be executed immediately, To be stored in the instance, it is executed by the callback function of the actuator
- Data acquisition successful
Execute the return promise state processing function and pass in the success callback function
- Data acquisition failed
Execute the return promise state processing function and pass in the failure callback function
- Data not available
Encapsulate the success / failure function, execute the return promise state processing function in the encapsulated function, and pass in the then success / failure callback
This wrapper function is ultimately executed by the success / callback function of the current promise instance
Finally, the data is processed by the return promise state processing function
- Data acquisition successful
3、 Definition Promise.resolve
Promise.resolve Receive three types of parameters and return a new promise instanceSuccessful promise instance failed promise instance is not an arbitrary value of promise instance
Promise.resolve Return promise architecture Determine whether the parameter is a promise instance. If so, call the then method and bind the success / failure function of return promise
The parameter is not promise. Call the return promise success function directly and pass in the parameter
4、 Definition Promise.all
Promise.all Receives an array of promise or other valuesIf all are successful, return promise will be executed and the result of promise will be passed in. If there is one failure, the failed return promise will be executed and the failure value will be passed in
Promise.all Return promise architecture Define an array container
Define a counter
Traverses the array (foreach), each time it enters the loop counter + 1
Execute each promise instance then. If successful, store the value in the array container according to the subscript
Judge whether the promise array length is equal to the counter. If it is, it means that the return promise successful function needs to be executed
If then fails, the return promise failure function is called directly and the then failure value is passed in
5、 Definition promise.rule
Promise.rule Receive an array of promise or other values. If a success / failure occurs, the return promise success / failure function is called directly
Implement the specific code
//! define common constants
//? not obtained, which means that the resolve of the current promise is completed asynchronously
const PENDING = 'pending'
//? obtained, which means that the current promise is executed synchronously
const RESOLVED = 'resolved'
//? failure, which means that the execution result of the current promise is failure
const REJECTED = 'rejected'
//! the three states can only be changed once from pending
function Promise(executor) {
const _this = this
//! promise constructor defines the initialization state as not obtained
_this.status = PENDING
//! promise constructor defines initialization data as undefined
_this.data = undefined
//! promise constructor definition initialization success container is undefined
_this.onResolved = undefined
//! promise constructor definition initialization failed, container is undefined
_this.onRejected = undefined
//! get success function
function resolve(value) {
//! if the status is not pending, return directly
if (_this.status !== PENDING) { return }
//! change status to get success
_this.status = RESOLVED
//! save data
_this.data = value
//! if the success function has been defined, it means that it needs to be executed asynchronously, successfully callback onresolved and pass in data
if (_this.onResolved) {
setTimeout(() => _this.onResolved(value));
}
}
//! get failed function
function reject(reason) {
//! if the status is not pending, return directly
if (_this.status !== PENDING) { return }
//! change status to get failed
_this.status = REJECTED
//! save data
_this.data = reason
//! if the failure function has been defined, it means that the failure callback onresolved should be executed asynchronously and the data should be passed in
if (_this.onRejected) {
setTimeout(() => _this.onRejected(reason));
}
}
try {
executor(resolve, reject)
} catch (error) {
//! if an error is caught, the result of then retrun promise is failure
//! then call the failure function of retrun promise directly, and fail to pass down
reject(error)
}
}
Promise.prototype = {
then: function (onResolved, onRejected) {
//! onresolved successful callback; onrejected failed callback;
const _this = this
//! when then is executed, a new promise is returned
//The execution result of! Return promise is determined by onresolved and onrejected
return new Promise((resolve, reject) => {
/*
There are three kinds of data acquisition situations
! data has been obtained successfully, which means that it can be directly executed and the onresolved return value can be obtained
! data acquisition failed. It means that you can directly execute and get the returned value of onrejected
! if the data is not obtained, it means onrejected. Onresolved cannot be executed immediately. It should be stored in the instance and executed by the callback function of the actuator
! - > and each state must be executed asynchronously
*/
if (_this.status === RESOLVED) {
//! data acquisition successful, execute return promise status processing function, and pass in successful callback
setTimeout(() => DealWithThenReturnPromise(onResolved));
} else if (this.status === REJECTED) {
//! data acquisition failed, execute return promise status processing function, and pass in failure callback
setTimeout(() => DealWithThenReturnPromise(onRejected));
} else {
//! if the data is not obtained yet, encapsulate the success / failure function, execute the return promise state processing function in the encapsulated function, and pass in the then success / failure callback,
//! this wrapper function is ultimately executed by the success / callback function of the current promise instance
//! when getting data, it will be obtained in dealwiththenreturnpromise function
_this.onResolved = value => DealWithThenReturnPromise(onResolved)
_this.onRejected = reason => DealWithThenReturnPromise(onRejected)
}
//! define the return promise function and pass in the success / failure function to be processed
function DealWithThenReturnPromise(callback) {
/*
There are three conditions to change the status of "returned"
! the execution result is an exception throw. Execute the failure function of return promise and pass in the exception data
Return / promise is the result of the successful execution of the function
! the execution result is not a promise instance. Execute the success function of return promise and pass in the execution result
*/
try {
//! save then success / failure return value
const result = callback(_this.data)
if (result instanceof Promise) {
//! the execution result is a promise instance, which determines the execution result of return promise
//Easy to understand result.then (value=> resolve(value), reason=> reject(reason))
//! easy to write
result.then(resolve, reject)
//! here, the success / failure callback of return promise is passed into the execution result instance then, so the resolve here has double meanings,
//! one is the onresolved and onrejected result instances of then,
//The second is resolve and reject of return project
} else {
//! the execution result is not a promise instance. Execute the return promise successful function and pass in the execution result
resolve(result)
}
} catch (error) {
//! the execution result is an exception throw. Catch the exception and execute the return promise failure function to pass in the exception
reject(error)
}
}
})
},
catch: function (reject) { return this.then(null, reject) },
}
Promise.resolve = function (value) {
/*
! Promise.resolve Reception has three parameters
! 1. The instance result is failed
! 2. The instance result is successful
! 3. Not an instance
*/
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
//! if value is an instance of promise
value.then(resolve, reject)
} else {
//! if not
resolve(value)
}
})
}
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
Promise.all = function (promises) {
//! create a counter
let resolveCount = 0
//! create array with specified length
const values = new Array(promises.length)
return new Promise((resolve, reject) => {
promises.forEach((item, index) => {
Promise.resolve(item).then(
value => {
//! counter + 1 when successful
resolveCount++
//! promise instance succeeded. The result is saved in the array
values[index] = value
//! when the last one is executed, execute the all return promise success function and pass in the array of success values
promises.length === resolveCount ? resolve(values) : []
},
//! as long as there is a failure, the promise returned by all is a failure
reason => reject(reason)
)
})
})
}
Promise.rule = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach(item => {
Promise.resolve(item).then(resolve, reject)
})
})
}