Have nothing to do, want to interview a series of questions, first to a classic handwritten Promise, will you? I can’t, so I’ll write a…
1. Promise explanation
If you want to implement a Promise by hand, you need to know the principle of the Promise and its internal process. It is important to know what to write, just like writing business split pages and dismantling components. Promise, as we know it, is an asynchronous object. You can pass a resolve, reject function as follows:
const pro = new Promise((res, rej) = > {
console.log('The promise is fulfilled.')})Copy the code
This is a big pity, which is a pity. Once the state of a Promise object changes, it will not change back again. This is actually a guarantee for our subsequent calls to the function. (PS: The code in the Promise object is executed synchronously)
Promise.then () : gets the normal result of the asynchronous task, promise.catch() : gets the abnormal result of the asynchronous task, promise.finaly() : the asynchronous task will execute whether it succeeds or not.
const pro = new Promise((res, rej) = > {
console.log('The promise is fulfilled.')
res('success')
// rej(' failed ')
})
pro
.then(res= > {
console.log(res)
})
.catch(rej= > {
console.log(rej)
})
.finally(() = > {
console.log('complete')})Copy the code
An important chained invocation of promises is that each Promise returns a Promise object that can be used to execute subsequent state method calls. If the logic needs to break, you can interrupt the chain call manually by throwing a throw error where the interrupt is needed.
There are also two methods used, promise.all (): multiple asynchronous tasks are processed concurrently, and all tasks are successfully executed before the result is obtained. Promise.race (): multiple asynchronous tasks are processed concurrently, and as long as one task is successfully executed, the result is obtained
The above is the content of the Promise, can also be said to be the function point separation, the following is our own handwriting a Promise link.
2. Write a Promise
- First, we write a myPromise class that implements a function argument and executes it as soon as it is passed
class myPromise{
constructor(immediate) {
/ / success
let resolve = () = > {}
/ / fail
let reject = () = > {}
// Execute the function immediately
immediate()
}
}
Copy the code
- Then define the three states in myPromise: pengding, depressing, and rejected
class myPromise {
constructor(immediate) {
this.state = 'pending'
this.value // The value on success
this.error // Failure value
/ / success
let resolve = (res) = > {
if (this.state === 'pending') {
this.state = 'fufilled'
this.value = res
}
}
/ / fail
let reject = (rej) = > {
if (this.state === 'pending') {
this.state = 'rejected'
this.error = rej
}
}
// Execute the function immediately
immediate(resolve, reject)
}
}
new myPromise((resolve, reject) = > {
resolve('It worked')})// console output Promise {state: "fufilled", value: "successful "}
Copy the code
- Next, implement the.then method
class myPromise {
constructor(immediate) {
this.state = 'pending'
this.value // The value on success
this.error // Failure value
/ / success
let resolve = (res) = > {
if (this.state === 'pending') {
this.state = 'fufilled'
this.value = res
}
}
/ / fail
let reject = (rej) = > {
if (this.state === 'pending') {
this.state = 'rejected'
this.error = rej
}
}
// Execute the function immediately
immediate(resolve, reject)
}
// Declare the then method
then (fufilledCall, rejectedCall) {
if (this.state === 'fufilled') {
fufilledCall(this.value)
}
if (this.state === 'rejected') {
rejectedCall(this.error)
}
}
}
new myPromise((resolve, reject) = > {
resolve('It worked')
})
.then(res= > {
console.log('Successful callback', res)
})
// Console output success callback success
Copy the code
- Then implement. Then chain call (complete code)
class myPromise {
constructor(immediate) {
this.state = 'pending'
this.value // The value on success
this.error // Failure value
/ / success
let resolve = (res) = > {
if (this.state === 'pending') {
this.state = 'fufilled'
this.value = res
}
}
/ / fail
let reject = (rej) = > {
if (this.state === 'pending') {
this.state = 'rejected'
this.error = rej
}
}
// Execute the function immediately
immediate(resolve, reject)
}
// Declare the then method
then (fufilledCall, rejectedCall) {
let promise2
promise2 = new myPromise((resolve, reject) = > {
if (this.state === 'fufilled') {
let x = fufilledCall(this.value);
resolvePromise(promise2, x, resolve, reject)
}
if (this.state === 'rejected') {
let x = rejectedCall(this.error);
resolvePromise(promise2, x, resolve, reject)
}
})
return promise2
}
}
/** * Function that handles promise recursion ** promise2 {promise} default return promise * x {*} our own return object * resolve * reject */
function resolvePromise (promise2, x, resolve, reject) {
// Loop reference error
if (x === promise2) {
// reject error throw
return reject(new TypeError('Chaining cycle detected for promise'));
}
// Lock to prevent multiple calls
let called;
// x is not null and x is an object or function
if(x ! =null && (typeof x === 'object' || typeof x === 'function')) {
try {
// A+ specifies the then method that declares then = x
let then = x.then;
// If then is a function, the default is Promise
if (typeof then === 'function') {
// then executes the first argument this, followed by a successful callback and a failed callback
then.call(x, y= > {
// Only one can be called for success or failure
if (called) return;
called = true;
// Core point 2: the result of resolve is still a promise
resolvePromise(promise2, y, resolve, reject);
}, err= > {
// Only one can be called for success or failure
if (called) return;
called = true;
reject(err);// If you fail, you fail})}else {
resolve(x); // You can do just that}}catch (e) { // Go to catch is also a failure
if (called) return;
called = true;
// Then is not validreject(e); }}else{ resolve(x); }}new myPromise((resolve, reject) = > {
resolve('It worked')
})
.then(res= > {
console.log('Successful callback', res)
return new myPromise((resolve, reject) = > {
resolve('hello world');
})
})
.then(res= > {
console.log('Successful callback 2', res)
return new myPromise((resolve, reject) = > {
resolve('haha')
})
})
.then(res= > {
console.log('Successful callback 3', res)
})
Copy the code
This is basically complete with a handwritten Promise, but every time you need to manually return an object in the.then, it’s not perfect. I haven’t thought of a good solution yet. There are good methods can also send out, let me learn.