This is a big pity. Promise has three states, which are pending, fulfilled and rejected. They have two state transitions:
- First, the process from pending state to depressing is processed through resolve
- Second, the process is processed from pending to Rejected and reject.
Because resolve handles asynchron with the instance itself, the program also throws a reject exception to end execution. Let’s take a look at the different types of JavaScript exceptions
The exception type of JavaScript
- Error: Indicates the basic Error type. All other wrong types inherit from this type. (Exceptions thrown during program execution generally have specific types, and Error types are generally exceptions thrown by developers themselves)
- SyntaxError: SyntaxError, also called parsing error. Represents a syntax specification that does not conform to the programming language. JavaScript is an interpreted language, and code execution goes through lexical analysis -> parsing -> syntax tree. In lexical analysis, char stream is converted into token stream. In syntactic analysis, token stream is generated into abstract syntax tree (AST). In both phases, the JavaScript engine throws a SyntaxError if it finds an unexpected/unconverted token or if the token order is not the expected one.
- TypeError: indicates TypeError. Indicates that the parameter or variable is not of the expected type.
- ReferenceError: ReferenceError. Every time a variable is created or defined, the name of the variable is written to a variable store. This variable store is like a Key store. Every time a variable is referenced, it goes to the store and finds the Key and returns the Value. It throws a ReferenceError
- RangError: indicates a boundary error. Represents an exception that occurs when the valid range is exceeded
- URIError: URL error. An exception thrown when the URL is invalid in a urI-related method call. It mainly includes encodeURI(), decodeURI(), encodeURIComponent(), decodeURIComponent(), escape() and unescape()
Promise source code implementation
- Promise constructor
function noop () {}
function Promise (fn) {
// Determine if the Promise is instantiated with the new keyword
if(! (this instanceof Promise)) {
throw new TypeError('Promise must be constructed via new')}// The argument to the instantiation Promise must be a function
if (typeoffn ! = ='function') {
throw new TypeError('Promise constructor\'s arguments is not a function')}// noop is an empty function if fn is passed noop and does nothing
if (fn === noop) return
// Promise deferred execution state
this._deferredState = 0
// Promise execution state
this._state = 0;
// Promise executes the result
this._value = null;
// Delay processing storage (array)
this._deferreds = null;
// Implement internal binding
doResolve(fn, this)}Copy the code
The Promise constructor mainly validates the way in which a Promise is instantiated and the parameters passed in when it is instantiated. Next are the variables that define the run state, run results, and so on within the Promise. _deferredStatePromise Deferred execution state when another promise is applied internally; _statePromise instance itself running state; _valuePromise the result of running the instance itself; _deferredsPromise internally calls asynchronous processing tasks, storing deferred processing functions until resolve or REJECT, which sign promises, is called. The doResolve() method implements the binding of the call function and the resolve and reject arguments that Promise returns on instantiation.
- doResolve
var LAST_ERROR = null
var IS_ERROR = {}
// tryCallTwo converts the two arguments of Promise's callback to a handler
function tryCallTwo(fn, a, b) {
try {
fn (a, b)
} catch (ex) {
LAST_ERROR = ex
return IS_ERROR
}
}
function doResolve (fn, promise) {
// The initial completed state is false
var done = false;
// The internal implementation of resolve and Reject passed in as instance Promise
var res = tryCallTwo(fn, function (value) {
// If so, stop execution
if (done) return;
// Set done to true for next judgment
done = true;
// Call the resolve handler
resolve(promise, value);
}, function (reason) { // reject internal implementation
if (done) return;
done = true;
// Call the reject method
reject(promise, reason);
});
When the tryCallTwo method throws an exception, set done to true and call the Reject handler
if(! done && res === IS_ERROR) { done =true; reject(promise, LAST_ERROR); }}Copy the code
Copy the above code
var LAST_ERROR = null
var IS_ERROR = {}
function noop () {}function tryCallTwo (fn, a, b) {
try {
fn(a, b)
} catch (ex) {
LAST_ERROR = ex
return IS_ERROR
}
}
function doResolve (fn, promise) {
var done = false
var res = tryCallTwo(fn, function (value) {
if (done) return
done = true
// resolve(promise, value)
}, function (reason) {
if (done) return
done = true
})
if(! done && res === IS_ERROR) { done =true}}class MyPromise {
constructor(fn) {
if (typeoffn ! = ='function') {
throw TypeError('Promise contructor\'s arguments is not a function')}if (fn === noop) return
this._state = 0
this._valule = null
this._deferredState = 0
this._deferreds = null
doResolve(fn, this)}}Copy the code
The difference between class and function declarations in ES6
- Function declarations can be promoted, while class declarations, like let declarations, cannot be promoted. They remain in a temporary dead zone until the declaration is actually executed
- All code in a class declaration automatically runs in strict mode, and you cannot force code out of strict mode execution
- In custom types, you need to manually specify a method as non-enumerable through the object.defineProperty () method; In a class, all methods are not enumerable
- Each class has an internal method named [[Constructor]], and calling methods that do not contain [[Constructor]] with the keyword new causes the program to throw an error
- Calling the class’s constructor in a way other than the keyword new causes the program to throw an error
- Changing the name of a class in a class results in an error
In the ES6 class, calling the class’s constructor in any way other than with the keyword new returns an error, so the MyPromise class does not make a judgment pointing to this
Refer to the blog
Source speed reading! A Promise that looks and writes like a dead Promise