“This is the 20th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.
portal
Tear Promise from zero hand, master the realization of the Promise principle (1) of the basic structure of the Promise
From scratch tear Promise, grasp the Promise realization principle (2) of the basic version of the Promise
Tear Promise from scratch, Master Promise realization principle (3) Callback what is hell
From scratch tear Promise, master the Promise realization principle (4) then method chain call preliminary implementation
From scratch tear Promise, master the Promise realization principle (5) then method chain call of the advanced implementation
Why is the callback of then method asynchronous microtask
(7) Then the core method of chain call resolvePromise
(8) The core method of chain call of then method resolvePromise is explored again
(9) Then method chain call core method resolvePromise complete
Tear Promise from scratch, master the realization principle of Promise (10)then method to complete all
Test whether all promises comply with PromiseA+ by learning how to implement promises (11)
What? Promise.resolve() can also return a failed Promise (12)
From zero hand tear Promise, grasp the realization principle of Promise (13) hand tear Promise finally method
Tear Promise from zero, grasp the realization principle of Promise (14) the all method of tear Promise
review
After last time, our Promise completed the all method, and now Promsie looks like this.
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise, x, resolve, reject) = > {
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * to determine whether x and promsie the same promise, Prevent an infinite loop *********************//////*********
if(x === promise) throw new TypeError('Chaining cycle detected for promise #<Promise>')
// 1. Determine whether 'x' is a base type or a reference type.
if(x ! = =null && /^(object|function)$/.test(typeof x)){
let then
Then attribute (' x.chen ') on 'x'. Reject 'if an exception is reported
try{
then = x.then
}catch(e){
reject(e)
}
//3. Determine if 'then' is a function. If it is a function, then it is' Promise ', if not 'resolve'
if(typeof then === 'function') {let called = false / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
try{
then.call(x, (y) = > {
if(called) return / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
called = true
resolvePromise(promise, y, resolve, reject)
},(r) = > {
if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
reject(r)
})
}catch(e){
if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
reject(e)
}
}else{
resolve(x)
}
}else{
// Base type data directly resolve
resolve(x)
}
}
class Promise{
constructor(executor){
this.state = PENDING
this.value = undefined
this.reason = undefined
/ / store onFulfilled
this.onResolvedCallbacks = []
/ / store onRejected
this.onRejectedCallbacks = []
const resolve = (value) = > {
// If we find that value is a Promise, we need to call value's then method to recursively resolve it
if(value instanceof Promise) {return value.then(resolve,reject); // recursive parsing
}
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
// The promise instance will call ondepressing after its state changes
this.onResolvedCallbacks.forEach(fn= > fn())
}
}
const reject = (reason) = > {
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
// onRejected called after the promise instance state changes
this.onRejectedCallbacks.forEach(fn= > fn())
}
}
try {
// An error in the execution of the executor function will cause the Promise to fail
executor(resolve,reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected){
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v
onRejected = typeof onRejected === 'function' ? onRejected : err= > { throw err }
let promise = new Promise((resolve, reject) = > {
switch(this.state){
case FULFILLED:
setTimeout(() = > {
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
break
case REJECTED:
setTimeout(() = > {
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
break
default:
this.onResolvedCallbacks.push(() = > {
setTimeout(() = > {
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
})
this.onRejectedCallbacks.push(() = > {
setTimeout(() = > {
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
})
}
})
return promise
}
catch(onRejected){
return this.then(null, onRejected)
}
finally(cb){
return this.then(
(y) = > {
return Promise.resolve(cb()).then(() = > y)
},
(r) = > {
return Promise.resolve(cb()).then(() = > {throw r})
}
)
}
static rsolve(value){
return new Promise((resolve,reject) = >{ resolve(value); })}static reject(reason){
return new Promise((resolve,reject) = >{ reject(reason); })}static all (promsies){
return new Promise((resolve, reject) = > {
const arr = []
let count = 0
const processResult = (i, val) = > {
arr[i] = val
if(++times === promises.length) resolve(arr)
}
for(let i = 0; i < promises.length; i++){
let val = promises[i]
if(typeof val.then === 'function'){
val.then(y= > processResult(i, y), reject)
}else{
processResult(i, val)
}
}
})
}
}
Copy the code
Promise.race
Realize the principle of
Promise.race
Method is alsoPromise
The static method of thePromise
The array. Only withPromise.all
In a different way,Promise.all
Is that all success is success, and one failure is failure.Promise.race
Is used to take the result of the fastest completed Promise as the final result.
Promise.race takes the results of the fastest Promsie as a result, but does not interrupt the execution of other promises, except that the other results are not taken, with no breaking effect. The characteristic of promsie. all is that all promsies succeed, one fails, and the other promsies are executed.
- Principle of implementation
static race(promises) {
return new Promsie((resolve, reject) = >{
for(let i = 0; i < promise.length; i++){
let p = promises[i]
Promise.resolve(p).then(resolve, reject)
}
})
}
Copy the code
finishing
So far, our Promsie has completed resolve, Reject, catch, finally, All, and race, and now the Promise is relatively complete. After a little tidying up, the Promise now looks like this.
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise, x, resolve, reject) = > {
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * to determine whether x and promsie the same promise, Prevent an infinite loop *********************//////*********
if(x === promise) throw new TypeError('Chaining cycle detected for promise #<Promise>')
// 1. Determine whether 'x' is a base type or a reference type.
if(x ! = =null && /^(object|function)$/.test(typeof x)){
let then
Then attribute (' x.chen ') on 'x'. Reject 'if an exception is reported
try{
then = x.then
}catch(e){
reject(e)
}
//3. Determine if 'then' is a function. If it is a function, then it is' Promise ', if not 'resolve'
if(typeof then === 'function') {let called = false / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
try{
then.call(x, (y) = > {
if(called) return / / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
called = true
resolvePromise(promise, y, resolve, reject)
},(r) = > {
if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
reject(r)
})
}catch(e){
if(called) return/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * added a variable here * * * * * * * * * * * * * * * * * * * * * * * * * / / / / / /
reject(e)
}
}else{
resolve(x)
}
}else{
// Base type data directly resolve
resolve(x)
}
}
class Promise{
constructor(executor){
this.state = PENDING
this.value = undefined
this.reason = undefined
/ / store onFulfilled
this.onResolvedCallbacks = []
/ / store onRejected
this.onRejectedCallbacks = []
const resolve = (value) = > {
// If we find that value is a Promise, we need to call value's then method to recursively resolve it
if(value instanceof Promise) {return value.then(resolve,reject); // recursive parsing
}
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
// The promise instance will call ondepressing after its state changes
this.onResolvedCallbacks.forEach(fn= > fn())
}
}
const reject = (reason) = > {
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
// onRejected called after the promise instance state changes
this.onRejectedCallbacks.forEach(fn= > fn())
}
}
try {
// An error in the execution of the executor function will cause the Promise to fail
executor(resolve,reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected){
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v
onRejected = typeof onRejected === 'function' ? onRejected : err= > { throw err }
let promise = new Promise((resolve, reject) = > {
switch(this.state){
case FULFILLED:
setTimeout(() = > {
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
break
case REJECTED:
setTimeout(() = > {
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
break
default:
this.onResolvedCallbacks.push(() = > {
setTimeout(() = > {
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
})
this.onRejectedCallbacks.push(() = > {
setTimeout(() = > {
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
})
}
})
return promise
}
catch(onRejected){
return this.then(null, onRejected)
}
finally(cb){
return this.then(
(y) = > {
return Promise.resolve(cb()).then(() = > y)
},
(r) = > {
return Promise.resolve(cb()).then(() = > {throw r})
}
)
}
static rsolve(value){
return new Promise((resolve,reject) = >{ resolve(value); })}static reject(reason){
return new Promise((resolve,reject) = >{ reject(reason); })}static all (promsies){
return new Promise((resolve, reject) = > {
const arr = []
let count = 0
const processResult = (i, val) = > {
arr[i] = val
if(++times === promises.length) resolve(arr)
}
for(let i = 0; i < promises.length; i++){
let val = promises[i]
if(typeof val.then === 'function'){
val.then(y= > processResult(i, y), reject)
}else{
processResult(i, val)
}
}
})
}
static race(promises) {
return new Promsie((resolve, reject) = >{
for(let i = 0; i < promise.length; i++){
let p = promises[i]
Promise.resolve(p).then(resolve, reject)
}
})
}
}
Copy the code
portal
Tear Promise from zero hand, master the realization of the Promise principle (1) of the basic structure of the Promise
From scratch tear Promise, grasp the Promise realization principle (2) of the basic version of the Promise
Tear Promise from scratch, Master Promise realization principle (3) Callback what is hell
From scratch tear Promise, master the Promise realization principle (4) then method chain call preliminary implementation
From scratch tear Promise, master the Promise realization principle (5) then method chain call of the advanced implementation
Why is the callback of then method asynchronous microtask
(7) Then the core method of chain call resolvePromise
(8) The core method of chain call of then method resolvePromise is explored again
(9) Then method chain call core method resolvePromise complete
Tear Promise from scratch, master the realization principle of Promise (10)then method to complete all
Test whether all promises comply with PromiseA+ by learning how to implement promises (11)
What? Promise.resolve() can also return a failed Promise (12)
From zero hand tear Promise, grasp the realization principle of Promise (13) hand tear Promise finally method
Tear Promise from zero, grasp the realization principle of Promise (14) the all method of tear Promise