Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
The preface
Promises are so common in writing code that we don’t always want to see them without knowing why.
When I mentioned the Promise when the interviewer asked, the result did not understand, not good ~ ha ha ha
Introduction to the
The Promise object is used to represent the final completion (or failure) of an asynchronous operation and its resulting value.
A Promise must be in one of three states
- Pending: The initial state, that is, not granted, nor rejected.
- This is a big pity: it means that the operation will be successful
- Rejected: Indicates that the operation fails
When pending is fulfilled or Rejected, the state will not change.
Solve a problem:
- Callback hell, code is hard to maintain
- Callbacks are subject to inversion of control
Realize the Promise
Grammar:
new Promise(executor)
Copy the code
The Promise implementation will execute the executor function immediately and pass in two functions. The Promise implementation will call resolve successfully and the state will become fulfilled. The Promise implementation will call reject and the state will become Rejected.
Design:
- Promise should be a constructor
- Passing in a parameter
function MyPromise(executor) { //1. Fix this, prevent resolve and reject from changing this, or use the arrow function let self = this; //2. The initial state of the Promise is pending self.state = "pending"; Self. value = undefined; // this is a big pity state array self. onrealdarr = []; // This is a big pity state array self. onrealdarr = []; Self. onRejectedArr = []; self.onRejectedArr = []; Function resolve(res) {//4.1 Determine whether the status is pending if (self.state! == "pending") return; // This is a big pity. State = "depressing "; //4.3 The result value is self.value = res; / / - 9. Call then array, backlog into self success. OnFulfilledArr. ForEach (item = > item ()); Function reject(err) {//5.1 Determine whether the state is pending if (self.state! == "pending") return; Self. State = "rejected"; //5.3 The result value is the passed parameter self.value = err; / / - 10. Call then array, backlog into self failure. OnRejectedArr. ForEach (item = > item ()); } //6. Execute executor try {executor(resolve, reject); }catch(err) { reject(err); }}Copy the code
Realize the Promise. Prototype. Then
The then method allows promises to support chained calls
Grammar:
p.then(onFulfilled[, onRejected]);
Copy the code
OnFulfilled and onRejected are optional
Note:
- The then method returns a Promise object
- Ondepressing is called when the state of the Promise changes to success, where the parameter is the one passed in to resolve
- Ondepressing is called when the promise state becomes a failure, with the parameter reject passing in the parameter
- The then method can be called multiple times
- Ondepressing is not a function, and then it will be replaced internally with (x) => x, which is the function that returns the final result of the promise as usual
- OnRejected is not a function and is internally replaced with a “Thrower” function.
let test2 = new Promise((resolve, reject) => {
resolve("hehe");
});
console.log(test2.then());
Copy the code
let test2 = new Promise((resolve, reject) => {
reject("hehe");
});
console.log(test2.then());
Copy the code
Design:
MyPromise.prototype.then = function (onFulfilled, onRejected) { //1. Fix this let self = this; //2. Judge whether ondepressing is a function if (typeof ondepressing! == "function") { onFulfilled = res => res; } //3. Check if (typeof onRejected! == "function") { onRejected = err => { throw err; }; // this will be a big pity if (self.state === "depressing ") {//4.1 Return the new promise object MyPromise((resolve, reject) => {try {// let x = ondepressing (self.value); If (x instanceof MyPromise) {if(x instanceof MyPromise) {if(x instanceof MyPromise) { err=>reject(err)); return; Resolve resolve(x); } catch (err) {//4.4 Catch error (err); }}); If (self. State === "rejected") {return new MyPromise((resolve, resolve)); Reject) => {try {let x = onRejected(self.value); if(x instanceof MyPromise) { x.then(res=>resolve(res), err=>reject(err)); return; } reject(x); } catch (err) { reject(err); }}); If (self.state === "pending") {return new MyPromise((resolve, resolve)); Reject) => {//6.1 since it is not clear whether to execute the successful state or the failed state, we need to store (7,8) in two arrays of Promise, and execute them when the state is finalized. self.onFulfilledArr.push(() => { try { let x = onFulfilled(self.value); resolve(x); } catch (err) { reject(err); }}); self.onRejectedArr.push(() => { try { let x = onRejected(self.value); reject(x); } catch (err) { reject(err); }}); }); }}Copy the code
Realize the Promise. The prototype. The catch
The catch method is used for error handling in the promise combination.
This is the second argument function to the then method
Example:
let temp = new Promise((resolve,reject)=>{
reject("temp");
});
temp.then(val=>console.log(val)).then(()=>console.log("2")).catch(err=>console.log(err));
Copy the code
Output: temp
Design:
MyPromise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected);
}
Copy the code
Realize the Promise. Resolve
Example: Pass in the Promise instance in the resolve method, returning itself
Design:
let temp = new Promise((resolve,reject)=>{
resolve("temp");
});
console.log(Promise.resolve(temp));
Copy the code
Pass in a non-PROMISE instance in the resolve method, return a new Promise value with a success state
let temp = 1;
console.log(Promise.resolve(temp));
Copy the code
Design:
MyPromise.resolve = function(res) {
if(res instanceof MyPromise) {
return res;
}
return new MyPromise((resolve,reject)=>resolve(res));
}
Copy the code
Realize the Promise. Reject
Return a Promise with a reason for the rejection
Design:
MyPromise.reject = function(err) {
return new MyPromise((resolve,reject)=>reject(err));
}
Copy the code
Realize the Promise. All
Return a Promise in which a Promise in the iterator is rejected
When there are multiple Promise combinations, all of which are completed, the Promise returned by promise. all becomes completed asynchronously, and if one of them rejects, the returned Promise directly invokes the failed Promise’s callback function
Grammar:
Promise.all(iterable);
Copy the code
Iterable: An iterable
Design:
Mypromise.all = function(mpArr) {const res = []; myPromise.all = function(mpArr) {const res = []; return new MyPromise((resolve, reject) => { mpArr.forEach((item, index) => { MyPromise.resolve(item).then(val=>{ res.push(val); If (index + 1 == mpar.length) {resolve(res); }}, err => {reject(err); }); }); }); }Copy the code
Realize the Promise. Race
Returns a promise that is resolved or rejected once a promise in the iterator is resolved or rejected.
That’s the Promise in the iterator that executes whoever finishes first
Grammar:
Promise.race(iterable);
Copy the code
Design:
MyPromise.race = function(mpArr) {
return new MyPromise((resolve, reject) => {
mpArr.forEach(item=>{
MyPromise.resolve(item).then(val=>{
resolve(val);
}, err => {
reject(err);
});
});
});
}
Copy the code
conclusion
Promise was few and far between in the pen tests I encountered, but I asked a lot in interviews. The accumulation of knowledge is not too much
Reference: MDN | Promise