I don’t want to write this article about why promises come into being or the problems they solve. I just want to write an article about fulfilling my Promise. If there is something wrong with the code and logic, please point it out. That’s it. Let’s get down to business.
Premise: We need to know that Promises are based on Promises/A+. Many of these variables and method names come from here. Let’s start with a few test examples of how Promise can be used.
let promise = new Promise((resolve, reject) =>{
// console.log("1");
// resolve("Success");
// reject("Failure");
// console.log("2"); // reject()"Failure");
// resolve("Success"); // Step 2 //setTimeout(() => {
// resolve("success");
// }, 2000);
throw new Error("Manual throw error"); // step 4}); promise.then((value) => { console.log("Then first method:"+value);
}, (err) => {
console.log("Then second method:"+err);
})
promise.then((value) => {
console.log("Then first method:"+value);
}, (err) => {
console.log("Then second method:"+err);
})
console.log("3");
Copy the code
Step 1 Output
- 1
- 2
- 3
- Then the first method: success
- Then the first method: success
Step 2 Output
- 3
- Then the second method: fail
- Then the second method: fail
Step 3 Output
- 3 Two seconds later
- Then the first method: success
- Then the first method: success
Step 4 Output
- 3
- Then the second method: Error: manually throws an Error
- Then the second method: Error: manually throws an Error
The final “success” output indicates that THEN is executed asynchronously
Based on the above examples, we can conclude the following:
- Promise is a constructor (uses new)
- A Promise takes an argument, and that argument is a function (we’ll call it executor for the sake of description)
- Executor executes on a new Promise
- Asynchronous behavior can be supported in New Promises (step 3)
- Executor takes two arguments (resolve,reject)
- Resolve and Reject will not be passed in, indicating that they are provided by promises
- Resolve and reject are functions, and each takes a single argument. Resolve is called value,reject is called reason
- There are then methods on each Promise instance
- The THEN method is asynchronous
- The then method has two parameters, onFulfilled and onRejected, which are the successful callback (resolve) and the failed callback (Reject), respectively. Look here
- Resolve and Reject are only implemented in a Promise. Promise States are mentioned in the specification
- An instance of the same Promise can then be repeated, calling all successful methods on success and all failed methods on failure
- If you find an error, you go into a failure state
It’s a big mess. It looks a little messy. We started writing our own promises based on our conclusions. As I write, my thoughts become clearer.
let myPromise = function (executor) {
letself = this; // Cache this self.status ='pending'; // The status management status can change from Pending to Resolved or Rejected. You can't both succeed and fail at the same time. So resolved and Rejected cannot be switched. self.value = undefined; // Pass the value to resolve self.reason = undefined; Reject self.onResolvedCallbacks = []; / / storethenSelf.onrejectedcallbacks = []; / / storethenThe third step is to use a timer. Once the new Promise is executed, it will be executedthenMethod, at this point, thethenThe method is cached and not executed: the state is still pending. Wait until the timer after 2 seconds, execute / / resolve | reject, but is executed in sequence that is stored in the array. Refer to the publish subscribe modelfunction resolve(value) {
// pending => resolved
if (self.status === 'pending') {
self.value = value;
self.status = 'resolved'; / / in order to perform the success of cache callback self. OnResolvedCallbacks. ForEach (fn = > fn (self. Value)); }}function reject(reason) {
// pending => rejected
if (self.status === 'pending') {
self.value = value;
self.status = 'rejected'; / / in turn perform caching failure callback self. OnRejectedCallbacks. ForEach (fn = > fn (self. "reason)); }} try {// New Promise executor executes executor(resolve, reject); } catch (error) { reject(error); Reject}} when there is an exception in the executor, execute reject}} // on each Promise instancethenMethods Promise. Prototype. Then =function (onFulfilled, onRejected) {
letself = this; // Resolve is executedif (self.status === 'resolved'// This is a big pity (self.value); } // reject is executedif (self.status === 'rejected') {// Execute the failed callback onRejected(self.reason); } // Async behavior can be supported in new Promise. The state is the default pending state when neither resolve nor Reject is executedif (self.status === 'pending') {/ / cache the success callback self. The onResolvedCallbacks. Push (onFulfilled); / / cache failed callback self. OnRejectedCallbacks. Push (onRejected); }};Copy the code
Just to be clear: this is the simplest version, because the power of Promise is the chained invocation. Ours is just a prototype, because of time. So let’s stop there. Next time we’ll implement A full version of Promises/A+ based on this prototype.
Publish article for the first time, hope everybody big shrimp many support.