当前位置:网站首页>Handwriting promise
Handwriting promise
2022-07-25 03:04:00 【Aviator_ huahua】
Handwriting Promise
Promise For a class , An actuator will be passed in for it during initialization , The actuator will execute immediately . The actuator receives two parameters :Promise Inside resolve and reject Method
Promise There are three states :Pending、Fulfilled、Rejected, The state can only be determined by Pending->Fulfilled or Pending->Rejected, Once the state changes, it is fixed , Cannot change again
Promise Use the inside resolve and reject Method change Promise state . In addition to changing the state when calling , It will also determine whether the callback functions that succeed or fail are cached , If it exists, the corresponding callback functions will be executed in sequence
then Method
then Method accepts two parameters , Success callback and failure callback . call then When the method is used , Will judge the status of the current instance , If the state is Fulfilled Call back successfully , If the status is failed, call the failure callback , If the state is Pending Cache the two callback functions , wait for resolve or reject Called when the
Of the same instance then Method can be called multiple times
then Method can be called in chain , The return value of its callback function will be passed to the next then Method . If the return value is a normal value , Call directly resolve Pass the value to the next then The successful callback of ; If the return value is promise Will be based on promise The result of execution , To call resolve Pass value or call reject Throw the failure reason
To avoid then The callback function calls circularly , You need to judge whether the return value of the callback function is then Oneself promise, if then Oneself promise Throw a type error exception
then The parameters of the method are optional , If you don't deliver , By default, a successful result is returned when it succeeds , Throw the failure reason when it failscatch Method
Internal call instance then Method returns a new one promise object ,then The successful callback in the method is set to undefined, The failure callback is set as the passed in parameter
finally Method
finally Method parameters receive a callback function , Back to a new promise, No matter what Promise The callback function will be called whether it succeeds or fails
Because you need to be in the last Promise After returning the result, execute the incoming callback, So you need to call the instance then Method , Call... In successful and failed callbacks respectively callback. if callback The return value is promise object , next then Callback function in method , Will wait promise Call after execution .Promise.resolve Static methods
Receive a parameter , If the parameter is Promise object , This parameter is returned directly ; If it is normal value , Then return to a new Promise object , and resolve This value
Promise.reject Static methods
Receive a parameter , Back to a new Promise object , and reject This value
Promise.all Static methods
Receive a parameter and return a new Promise object , This parameter is an array ,all Method will wait for the successful results of all members in the array to return , Uniformly return the result array containing the corresponding result .
If the return result of one of the members is failure , Then throw the failure reason immediatelyPromise.race Static methods
Receive a parameter and return a new Promise object , This parameter is an array ,race Method will wait for the first result returned from the array member , Take the result as yourself Promise Value .
const PENDING = 'Pending'
const FULFILLED = 'Fulfilled'
const REJECTED = 'Rejected'
class MyPromise {
// Constructors , Receive an actuator
constructor(executor) {
try {
executor(this.resolve, this.reject)
} catch (e) {
this.reject(e)
}
}
// The status value
status = PENDING
// Successful results
value = undefined
// The reason for the failure
reason = undefined
// Successful callback
successCallback = []
// Failed callback
failCallback = []
// resolve and reject Methods are called directly within the actuator , Ordinary function direct call ,this Point to window or undefined, To ensure internal this Point to MyPromise Instance object , You need to use the arrow function . If you use ordinary functions , You need to give executor Bind when passing parameters this(executor(this.resolve.bind(this),this.reject.bind(this)))
resolve = (value) => {
// The state can only be determined by pending->fulfilled or pending->rejected, And once the state changes, it solidifies , Repeated calls to resolve/reject It cannot be modified again
if (this.status === PENDING) {
// Status changed to successful
this.status = FULFILLED
// Save the result successfully
this.value = value
// Determine whether there is a successful callback function
while (this.successCallback.length) this.successCallback.shift()()
}
}
// resolve and reject Methods are called directly within the actuator , Ordinary function direct call ,this Point to window or undefined, To ensure internal this Point to MyPromise Instance object , You need to use the arrow function . If you use ordinary functions , You need to give executor Bind when passing parameters this(executor(this.resolve.bind(this),this.reject.bind(this)))
reject = (reason) => {
// The state can only be determined by pending->fulfilled or pending->rejected, And once the state changes, it solidifies , Repeated calls to resolve/reject It cannot be modified again
if (this.status === PENDING) {
// Change the status to failed
this.status = REJECTED
// Save the result successfully
this.reason = reason
// Determine whether there is a failed callback function
while (this.failCallback.length) this.failCallback.shift()()
}
}
//then Method calls none for the instance this Point to the problem (p1.then()), And all instances can call this method , It should be defined on the prototype object
then(successCallback, failCallback) {
// then Method parameters are optional values
successCallback = successCallback ? successCallback : value => value;
failCallback = failCallback ? failCallback : reason => {
throw reason
};
let thenPromise = new MyPromise((resolve, reject) => {
// Judge the state
if (this.status === FULFILLED) {
try {
// Through asynchrony , Let the synchronization code execute first , In order to get thenPromise
setTimeout(() => {
// success
let result = successCallback(this.value)
// Judge whether the result of the callback function is Promise object , Is it thenPromise In itself
resolvePromise(thenPromise, result, resolve, reject)
}, 0)
} catch (e) {
reject(e)
}
} else if (this.status === REJECTED) {
try {
setTimeout(() => {
// Failure
let reason = failCallback(this.reason)
// Judge whether the result of the callback function is Promise object , Is it thenPromise In itself
resolvePromise(thenPromise, reason, resolve, reject)
}, 0)
} catch (e) {
reject(e)
}
} else {
// wait for
// Save success or failure callback function , wait for resolve or reject Execute... On call
this.successCallback.push(() => {
try {
setTimeout(() => {
// success
let result = successCallback(this.value)
// Judge whether the result of the callback function is Promise object , Is it thenPromise In itself
resolvePromise(thenPromise, result, resolve, reject)
}, 0)
} catch (e) {
reject(e)
}
})
this.failCallback.push(() => {
try {
setTimeout(() => {
// Failure
let reason = failCallback(this.reason)
// Judge whether the result of the callback function is Promise object , Is it thenPromise In itself
resolvePromise(thenPromise, reason, resolve, reject)
}, 0)
} catch (e) {
reject(e)
}
})
}
})
return thenPromise;
}
// catch Method Receive a failed callback function
catch (failCallback) {
return this.then(undefined, failCallback)
}
// finally Method Return to one promise, No matter success or failure, it will call callback, And finally follow-up then The callback in will wait callback Execute after execution .
finally(callback) {
return this.then(value => {
// Note here , take then The successful callback of returns the above value value , Instead of returning its own return value , So you need to define a successful callback () => value. Failed callback is not defined ,then Internal automatic assignment reason=>{throw reason} Throw your own exception .
MyPromise.resolve(callback()).then(() => value)
}, reason => {
// Note here , take then The successful callback of throws the above reason abnormal , Instead of returning its own return value , So you need to define a successful callback () => {throw reason}. Failed callback is not defined ,then Internal automatic assignment reason=>{throw reason} Throw your own exception .
MyPromise.resolve(callback()).then(() => {
throw reason
})
})
}
// MyPromise.resolve
static resolve(value) {
// Judge whether it is promise object
// Parameter is Promise object , Go straight back to
if (value instanceof MyPromise) return value;
// The parameter is not Promise object , return new MyPromise
return new MyPromise(resolve => resolve(value))
}
// MyPromise.reject
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason))
}
// MyPromise.all As asynchronous API Call sequence gets asynchronous API The results of the implementation of , Get the successful results of all members and return them together , If it fails, the failure reason of the member will be returned immediately
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject) => {
// Declare add method
function addData(key, value) {
result[key] = value
index++
// You can't write result.length === array.length, because result[n]=value when ,result The length of is already n 了
if (index === array.length)
resolve(result)
}
// Traverse the parameter array
for (let i = 0; i < array.length; i++) {
const item = array[i];
// Judge whether it is promise object
if (item instanceof MyPromise) {
// promise object In the callback function, send a message to result Add the return result
item.then(value => addData(i, value), reason => reject(reason))
} else {
// Common value
addData(i, item)
}
}
})
}
// MyPromise.race Wait for the first result returned in the array member , Return the result as your own Promise Value
static race(array) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < array.length; i++) {
const item = array[i];
if (item instanceof MyPromise) {
item.then(resolve, reject)
} else {
resolve(item)
}
}
})
}
}
// Judge successRes Is it normal or promise object
// If it's a normal value , Call directly resolve Return results .
// If it is promise object , It is necessary to judge its status . If it is Fulfilled, call resolve; If it is Rejected, call reject.
// Judge whether the return result of the callback function is thenPromise In itself , Avoid loop calls
function resolvePromise(thenPromise, result, resolve, reject) {
// Determine whether to return to itself
if (result === thenPromise) {
return reject(new TypeError('[TypeError: Chaining cycle detected for promise #<Promise>]'))
}
if (result instanceof MyPromise) {
// promise object
result.then(resolve, reject)
} else {
// Common value
resolve(result)
}
}
module.exports = MyPromise
边栏推荐
- Request and response
- Solve the error: could not find 'xxxtest‘
- Color space (2) -- YUV
- How to switch terminators in PostgreSQL?
- Decoding webp static pictures using libwebp
- Learning Record V
- Dc-2-range practice
- Concurrent programming day01
- Ffmpeg 4.3 add custom demuxer
- Clothing ERP | ten advantages of clothing ERP for enterprises
猜你喜欢

Learning record 12

Pypi counts the number of Downloads

Dynamic programming -- Digital DP

PHP record

Decoding webp static pictures using libwebp

Get to know string thoroughly

Riotboard development board series notes (VIII) -- building desktop system

Define macros in makefile and pass them to source code

Bgy development small example

If there is a segment in the encryption field, are you "bronze" or "King"?
随机推荐
Details of happens before rules
Method of adding kernel in Jupiter notebook
SQL recursive follow-up
Concurrent programming day01
JS foundation -- math
Wechat sports field reservation of the finished works of the applet graduation project (6) opening defense ppt
@Retryable @backoff @recover retry the use of annotations
Physical experiment simulation
kettle_ Configure database connection_ report errors
Map set learning
Innobackupex parameter description
Go multiplexing
[pyGame practice] nostalgic classic - do you remember the name of this chess game for children? (must collect)
The dolphin scheduler calls the shell script and passes multiple parameters
"Introduction to interface testing" punch in to learn day05: how can a testing framework support restful interfaces?
mysql_ Backup restore_ Specify table_ Backup table_ Restore table_ innobackup
Learning record XIII
Dynamic programming -- Digital DP
Flume's study notes
# CF #807 Div.2(A - D)