In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to understand core.js in Promise". The content of the explanation in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to understand core.js in Promise".
Source code reading phase
First understand the basics of Promise, if you want to understand quickly, you can skip to the next title. This part will continue to be revised according to understanding.
Promise (fn)
Function noop () {} / * null function, which is used to determine whether the function passed into the Promise constructor is an empty function. If a promise object is constructed for the empty function and the initialization state is pending, the final value null, callback state 0 and queue null. * / var LAST_ERROR = null;// record an error within the Promise var IS_ERROR = {}; / / an empty object indicates that an error has occurred module.exports = Promise; / / expose that the module interface is Promise function Promise (fn) {if (typeof this! = = 'object') {throw new TypeError (' Promises must be constructed via new') } if (typeof fn! = = 'function') {throw new TypeError (' Promise constructor\'s argument is not a function');} this._deferredState = 0; this._state = 0; / / promise status this._value = null; / / resolve returned result this._deferreds = null; if (fn = = noop) return; doResolve (fn, this); / / handler function} Promise._onHandle = null; Promise._onReject = null Promise._noop = noop
The original text indicates that variables with the _ prefix will be constructed in the form of (_ random numbers) to confuse and prevent them from being used. Next, list the important variables that describe them.
* _ defferedState = 0 indicates the type of _ deferreds, 0 indicates null, 1 indicates a single handler (described later), 2 indicates multiple deferreds (array) * _ state = 0 promise state, 0 indicates pending,1 is fulfilled,2 and rejected,3 indicates that the value has been passed to the next promise. The result returned by * _ value = null resolve, which is what we call the final value / reject cause * _ deferreds = null represents single or multiple handler (described later)
DoResolve (fn,this)
Compared to doResolve (fn this); which is what we do when we initialize a Promise, before we look at this function, we first understand the functions in the source code that are similar to utility functions.
/ / get then method, no then method identifies error function getThen (obj) {try {return obj.then;} catch (ex) {LAST_ERROR = ex; return IS_ERROR;}} / / internally catch error, single parameter function function tryCallOne (fn, a) {try {return fn (a);} catch (ex) {LAST_ERROR = ex; return IS_ERROR Function tryCallTwo (fn, a, b) {try {fn (a, b);} catch (ex) {LAST_ERROR = ex; return IS_ERROR;}}
Next, let's jump directly to doResolve (fn,promise):
The function doResolve (fn, promise) {/ / input parameter is a function, and a promise object var done = false; / / ensures that the one-time var res = tryCallTwo (fn, function (value) {/ / see) mentioned in the specification is used to catch errors. If (done) return; / / needless to say here, in order to ensure that only one of the two functions runs and runs only once done = true; resolve (promise, value); / / analyze it later}, function (reason) {if (done) return; done = true; reject (promise, reason); / / later analyze it}); if (! done & & res = = IS_ERROR) {done = true Reject (promise, LAST_ERROR); / / analyze it later}}
This is our doResolve function, as you can see, it is just a middleware, used for what, is to solve the incoming function error problem and reject. The point is to call two functions that we are familiar with, resolve () and reject ().
Resolve () and reject ()
We found two new things in this function, resolve () and reject (). You can see what these two functions are by looking at the name. Let's look at reject () first.
Function reject (self, newValue) {/ / two parameters, from doResolve we can know that self is a promise object, and newValue is because self._state = 2 is a rejected, and the result in self._value = newValue;//promise becomes if (Promise._onReject) {/ / it is null in core.js, so it may be used for other functions. Let's just skip Promise._onReject (self, newValue);} finale (self); / / A new function appears again. }
The reject () function passes in a promise object and a reason rejection. All the function does is change the state of promise to rejected and change the value of promise. Then call the finale () function.
You can see that the new function finale () appears and passes it the promise object that has finished reject. But let's look at resolve () first!
Function resolve (self, newValue) {/ / what is written here is actually the process handled according to the specification / * Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure * / if (newValue = self) {/ / throw error return reject (self, new TypeError ('A promise cannot be resolved with itself.')) if the incoming value equals itself. } if (/ / value is object or function newValue & & (typeof newValue = 'object' | | typeof newValue = =' function')) {var then = getThen (newValue); / / get the then function if (then = IS_ERROR) {/ / there is no then,reject return reject (self, LAST_ERROR) } if (/ / exists and the original value is a promise object then = self.then & & newValue instanceof Promise) {/ / synchronizes two promise, changes the incoming promise state to be passed and takes the promise object newValue as the value of promise, and then finale and exits the function. Self._state = 3; self._value = newValue; finale (self); return;} else if (typeof then = 'function') {/ / if the value obtained from then is not promise, but then is a function (thenable) doResolve (then.bind (newValue), self); / / you can take a look at the previous blog post to explain this situation, and doResolve the final value itself to get a new value as the new final value. Return;}} self._state = 1 the crash status is fulfilled self._value = newValue;// value passing finale (self); / / finale}
In resolve (), we still pass in a promise object and value (final value). Through standard judgment (see Learning Notes (2): specification for details), we do [Resolve] operation, * * change the state of promise object to fulfilled and change its final value, and call finale.
Finale ()
We can do the finale () analysis, after all, our core functions point to it!
Function finale (self) {/ / passes in a promise object if (self._deferredState = 1) {/ / determines that deferreds is a single handle (self, self._deferreds); / / passes in _ deferreds self._deferreds = null;// in the promise object and promise object so that deferreds is null} if (self._deferredState = = 2) {/ / determines that deferreds is an array for (var I = 0; I < self._deferreds.length) Handle +) {handle (self, self._ deferreds [I]); / all data passed in the promise object and the _ deferreds array in the promise object} self._deferreds = null;// let deferreds be null}}
Good, this is all new, _ deferredState this is to determine whether _ deferreds is an array or a single case, and make a handle call to each of these deferred. But what is _ defferreds, and what does the function handle () do?
Handle ()
Function handle (self, deferred) {/ / this input parameter is the expected while (self._state = 3) {/ / promise status is 3, that is, when the promise has been passed, self = self._value;// relocates the value passed by self to promise} if (Promise._onHandle) {/ / also does not fall within the scope of this article Promise._onHandle (self) } if (self._state = 0) {/ / if when the state of promise is pending (self._deferredState = 0) {/ / without deferreds, self._deferredState = 1 deferred; deferred; deferreds is listed as return;} if (self._deferredState = = 1) {self._deferredState = 2 hand if becomes array self._deferreds = [self._deferreds, deferred] / / input deferred into the array return;} self._deferreds.push (deferred); / / if it is already an array, add return;} handleResolved (self, deferred) directly to push; / / New things, pass promise and defered} when statekeeper = 0
You can see that this function is actually adding _ deferreds, modifying and writing _ deferreds, which is the opposite of what finale () does, but the detailed processing is still in the handleResolved () function.
HandleResolved ()
Function handleResolved (self, deferred) {asap (function () {/ / Note! asap is an introduced module, meaning as soon as possible, which means to execute as soon as possible, we do not need to consider what it has done. / / promise state is the Fulfilled function in deferred in the case of fulfilled. If not, it is the onRejected function. Var cb = self._state = = 1? Deferred.onFulfilled: deferred.onRejected; if (cb = = null) {/ / if there is no corresponding state function if (self._state = 1) {/ / whether the current promise object is fulfilled state resolve (deferred.promise, self._value); / / pass in the values of promise and current promise saved in deferred to resolve} else {reject (deferred.promise, self._value) / / similar to the above, reject} return;} var ret = tryCallOne (cb, self._value); / / attempt to execute the corresponding function and return the execution result (unlike the tryCall with two parameters, the function running result is returned here) if (ret = IS_ERROR) {/ / error, reject reject (deferred.promise, LAST_ERROR) } else {/ / No error, resolve resolve (deferred.promise, ret) with the function return value to deferred.promise;}});}
Here we see that deferred is an object that stores promise objects, onFulfilled functions, and onRejected functions, which is equivalent to a save site. In fact, here is the handler object that we are about to write in the source code core.js parsing (part two). But let's not delve into it for the time being, and it would be nice to know.
There is no doubt that handleResolved () is passing the final value of promise, modifying the state of the old promise object, and calling resolve and reject to get the value / reject to pass to the next Promise. For the detailed example analysis here, let's talk about it (below).
What happens when you construct a Promise?
From a simple point of view, what functions do we go through when we construct a Promise object.
Let's get this straight.
Var A = Promise (function (resolve,reject) {resolve ("ok");})
The first thing in this is to construct the Promise object, which we call A, and execute the following code during the construction phase.
Check the outline.
A._deferredState = 0; A._state = 0; A._value = null; A._deferreds = null
Check that the incoming parameter is not empty.
DoResolve (function resolve,reject) {resolve ("ok");}, this)
Then we jump to the doResolve () function and pass it as fn,promise
Res = tryCallTwo (fn,function (value) {resolve (promise, value);}, function (reason) {reject (promise, reason);}); reject (promise,LAST_ERROR)
Reject (promise,LAST_ERROR) if you make a mistake
We jump to resolve (promise,value) again according to our input. Let's take a look at our function. Promise is A _ ok value, which is actually the "ok" we passed in.
So resolve (promise, "ok") in the promise is executed.
After a series of judgments (details can be seen in the specification), our "ok" will be carried out directly to this step.
Self._state = 1 Splash A state changes to fulfilled self._value = newValue;//AA final value becomes "ok"
Then we finale (self), continue to jump to the finale () function, and pass in A.
/ / in the process, our _ deferredState is always 0, take a look at A._deferredState = 0; / / there is nothing left to do. Thank you for your reading, the above is the content of "how to understand core.js in Promise". After the study of this article, I believe you have a deeper understanding of how to understand core.js in Promise, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.