Written in the beginning
- ES6 common but ignored methods series of articles, sorting out the author thinks that some daily development may use some methods, use skills and some application scenarios, details please see related content links, welcome to supplement exchange.
Related articles
- Common but overlooked methods for ES6 (Destruct assignments and values first)
- ES6 Common but ignored methods (second bullet functions, arrays, and objects)
- ES6 common but ignored methods (third bullet Symbol, Set, and Map)
- ES6 commonly used but overlooked methods (fourth bullet Proxy and Reflect)
- Common but ignored methods for ES6 (Generator 6)
- ES6 Common but ignored methods (async)
- ES6 Common but ignored methods (eighth bullet Class)
- ES6 common but ignored methods (Module 9)
- Common but ignored methods of ES6 (Development specification of the Tenth Bullet Project)
- ES6 common but ignored method (eleventh bullet Decorator)
- Common but overlooked approaches to ES6 (End game – Latest Proposal)
Promise
- ES6-Promise
- Take a look at the most fully written implementation of ES6 Promise
Promise
Is a solution to asynchronous programming that is more reasonable and powerful than the traditional solution of callback functions and events.
The characteristics of
- The status of an object is not affected. There are three states:
pending
(In progress),fulfilled
(Successfully) andrejected
(Failed). Only the result of an asynchronous operation can determine the current state, and no other operation can change the state. - Once the state changes, it never changes again, and you can get this result at any time.
Promise
The state of an object can change in only two ways: frompending
intofulfilled
And from thepending
intorejected
.
use
Promise
The object is a constructor, used to generatePromise
Instance. The constructor takes as an argument a function whose two arguments areresolve
andreject
.resolve
What the function does is it takesPromise
The state of the object changes from Incomplete to Succeeded (that is, frompending
intoresolved
);reject
What the function does is it takesPromise
The state of the object changes from incomplete to Failed (that is, frompending
intorejected
).
Const promise = new promise (function(resolve, reject) {resolve(value); } else { reject(error); }});Copy the code
Promise
After the instance is generated, you can usethen
Methods specified separatelyresolved
State andrejected
State callback function. A method can take two callback functions as arguments. The first callback function isPromise
The object status becomesresolved
The second callback function is calledPromise
The object status becomesrejected
When the call. The second function is optional and does not have to be provided.
promise.then(function(value) {
// success
}, function(error) {
// failure
});
Copy the code
Promise
It will be executed immediately after being created.then
Method that will not execute until all synchronization tasks in the current script have been completed.JavaScript event loop mechanism
Promise.resolve()
- Convert an existing object to
Promise
Object. - Different parameters:
- The parameter is a
Promise
Instance, which is returned directly. - The parameter is a
thenable
Object (thenable
Object refers to havingthen
Method) to convert the object toPromise
Object, and execute immediatelythenable
The object’sthen
Methods.
let thenable = { then: function(resolve, reject) { resolve(42); }}; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); / / 42});Copy the code
- Parameter does not have
then
Method object, or not object at all, returns a new onePromise
Object in the state ofresolved
.
const p = Promise.resolve('detanx'); p.then(function (s){ console.log(s) }); // detanx Copy the code
- Returns one without any arguments
resolved
The state of thePromise
Object.immediatelyresolve()
thePromise
Object in this “event loop” (event loop
), rather than at the beginning of the next “event loop”.
setTimeout(function () { console.log('three'); }, 0); Promise.resolve().then(function () { console.log('two'); }); console.log('one'); // one // two // three Copy the code
- The parameter is a
Promise.reject()
Promise.reject(reason)
The method also returns a new onePromise
Instance, whose state isrejected
.Promise.reject()
The parameters of the method are left as they arereject
Becomes the parameter of the subsequent method.To this point andPromise.resolve
Methods are inconsistent.
Const thenable = {then(resolve, reject) {reject(' error '); }}; Promise.reject(thenable) .catch(e => { console.log(e === thenable) }) // trueCopy the code
Promise.prototype.catch()
Promise.prototype.catch()
Method is.then(null, rejection)
or.then(undefined, rejection)
Alias for thehandwrittenPromise
The method is implemented), which specifies the callback function in case of an error.
// const promise = new promise (function(resolve, reject) {try {throw new Error('test'); } catch(e) { reject(e); }}); promise.catch(function(error) { console.log(error); }); // const promise = new promise (resolve, reject) {reject(new Error('test')); }); promise.catch(function(error) { console.log(error); });Copy the code
- if
Promise
The state has becomeresolved
Throwing an error is invalid.
const promise = new Promise(function(resolve, reject) {
resolve('ok');
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })
.catch(function(error) { console.log(error) });
// ok
Copy the code
Promise
Object errors are “bubbling” and are passed backwards until they are caught.
getJSON('/post/1.json').then(function(post) { return getJSON(post.commentURL); }). Then (function(comments) {// some code}). Catch (function(error) {//Copy the code
- Generally not in
then()
Method defined inReject
The state callback function (i.ethen
The second argument) is always usedcatch
Methods.
// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
Copy the code
- With the traditional
try/catch
The code block is different if not usedcatch()
Method specifies the error handling callback function,Promise
An error thrown by an object is not passed to the outer code, that is, there is no response.
Const someAsyncThing = function() {return new Promise(resolve(x + 2)); }); }; someAsyncThing().then(function() { console.log('everything is great'); }); setTimeout(() => { console.log(123) }, 2000); // Uncaught (in promise) ReferenceError: x is not defined // 123Copy the code
Promise.prototype.finally()
finally()
Method is used to specify whetherPromise
The operation to be performed in the final state of the object.The method isES2018
Introduce standard.
Promise. Then (result = > {...}). The catch (error = > {...}), finally (() = > {the console. The log (' detanx '); }); // 'detanx'Copy the code
finally
The method’s callback function does not take any arguments, which means there is no way to know the previous onePromise
Is the statefulfilled
orrejected
. The operations within a method should be state independent and not dependent onPromise
The execution result of.finally
The method always returns the original value.
/ / implementation Promise. Prototype. Finally = function (the callback) {let P = this. Constructor; return this.then( value => P.resolve(callback()).then(() => value), reason => P.resolve(callback()).then(() => { throw reason }) ); }; // use undefined promise.resolve (2). Then (() => {}, () => {}) // use undefined promise.reject ().reject() => {}). Then () => {}, () = > {}) / / reject a value of 3 Promise. Reject (3) finally (() = > {})Copy the code
Promise.all(), promise.race () and promise.allSettled ()
- The same
- Methods are used to combine multiple
Promise
Instance, wrapped into a new onePromise
Instance. Promise.all()
All instances return yesfulfilled
And when thePromise.allSettled()
All return values are arrays.
- Methods are used to combine multiple
- The difference between
- Sometimes we don’t care about the results of asynchronous operations, only whether they end or not. At this time,
Promise.allSettled()
The method is very useful. Without this method, it would be a hassle to make sure everything was done.Promise.all()
Methods do not do this.
const urls = [ /* ... */ ]; const requests = urls.map(x => fetch(x)); try { await Promise.all(requests); Console. log(' All requests were successful. '); } catch {console.log(' At least one request failed, others may not be finished. '); }Copy the code
Promise.all()
One of all instances isrejected
.p
The state of theta becomes thetarejected
At this point, the first is returnedreject
The value of the instance of.Promise.allSettled()
In the instancefulfilled
When, the object hasvalue
Properties,rejected
From time to tomereason
Property corresponding to the return values of the two states.
const resolved = Promise.resolve(42); const rejected = Promise.reject(-1); const allSettledPromise = Promise.allSettled([resolved, rejected]); allSettledPromise.then(function (results) { console.log(results); }); // [ // { status: 'fulfilled', value: 42 }, // { status: 'rejected', reason: -1 } // ] Copy the code
- If it’s a parameter
Promise
Example, you define it yourselfcatch
Method, then once it isrejected
, does not triggerPromise.all()
thecatch
Methods. If the instance does not have its owncatch
Method is calledPromise.all()
thecatch
Methods.
const p1 = new Promise((resolve, reject) => { resolve('hello'); }) .then(result => result) .catch(e => e); Const p2 = new Promise((resolve, reject) => {throw new Error(' Error '); }). Then (result => result) => / Promise.all([p1, p2]) .then(result => console.log(result)) .catch(e => console.log(e)); // ["hello", Error: Error] => // remove p2 catch // // Error: ErrorCopy the code
Promise.race()
As long as one instance changes the state first, the state changes. The one who changed firstPromise
The return value of the instance is passed to the callback function.
const p = Promise.race([1, new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('request timeout')), 5000) }) ]); p .then(console.log) .catch(console.error); / / 1Copy the code
- Sometimes we don’t care about the results of asynchronous operations, only whether they end or not. At this time,
The Iterator and for… Of circulation
- ES6 Iterator and for… Of circulation
- It is an interface that provides a unified access mechanism for various data structures. The Iterator interface can be deployed on any data structure to complete traversal (that is, processing all members of the data structure in turn).
Iterator
The role of:- To provide a unified and simple access interface for various data structures;
- To enable the members of a data structure to be arranged in some order;
- New traversal command
for... of
Cycle,Iterator
Interface mainly forfor... of
Consumption.
- Traversal process:
- Creates a pointer object that points to the start of the current data structure. That is, the traverser object is essentially a pointer object.
- The first time a pointer object is called
next
Method to point to the first member of a data structure. - The second call to the pointer object
next
Method, which points to the second member of the data structure. - That constantly calls the pointer object
next
Method until it points to the end of the data structure.
- Every call
next
Method, which returns information about the current member of the data structure (returns a containvalue
anddone
Object with two properties.value
Property is the value of the current member,done
Property is a Boolean value indicating whether the traversal is complete.
var it = makeIterator(['a', 'b']); it.next() // { value: "a", done: false } it.next() // { value: "b", done: false } it.next() // { value: undefined, done: true } function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {value: undefined, done: true}; }}; }Copy the code
- For the traverser object,
done: false
andvalue: undefined
Attributes can be omitted.
Function makeIterator(array) {var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++]} : {done: true}; }}; }Copy the code
- use
TypeScript
The writing of- Traverser interface (
可迭代
), pointer object (Iterator
) andnext
The specification of the method return value can be described as follows.
interface Iterable { [Symbol.iterator]() : Iterator, } interface Iterator { next(value? : any) : IterationResult, } interface IterationResult { value: any, done: boolean, }Copy the code
- Traverser interface (
The default Iterator interface
- When using
for... of
When a loop iterates over some data structure, the loop automatically looks for itIterator
Interface. The defaultIterator
The interface is deployed in the data structureSymbol.iterator
Property, or a data structure that hasSymbol.iterator
Properties can be considered “traversable” (可迭代
).
const obj = { [Symbol.iterator] : function () { return { next: function () { return { value: 1, done: true }; }}; }};Copy the code
- The native has
Iterator
Interface data structure:Array
,Map
,Set
,String
,TypedArray
, the function ofarguments
Objects,NodeList
object. - If an object is to be able to be
for... of
Circularly calledIterator
Interface, must be inSymbol.iterator
Deploys the traverser generation method on the property of the
class RangeIterator { constructor(start, stop) { this.value = start; this.stop = stop; } [Symbol.iterator]() { return this; } next() { var value = this.value; if (value < this.stop) { this.value++; return {done: false, value: value}; } return {done: true, value: undefined}; } } function range(start, stop) { return new RangeIterator(start, stop); } for (var value of range(0, 3)) { console.log(value); // 0, 1, 2}Copy the code
- The array-like object calls the array’s
Symbol.iterator
Traversal; Common objects deploy arraysSymbol.iterator
Method, and no effect.
Iterable = {0: 'a', 1: 'b', 2: 'c', length: 3, [symbol.iterator]: array. prototype[symbol.iterator]}; for (let item of iterable) { console.log(item); / / 'a', 'b', 'c'} / / ordinary objects, the subscript is not digital let iterable = {a: 'a', b: 'b', c: 'c', length: 3, [Symbol. The iterator] : Array.prototype[Symbol.iterator] }; for (let item of iterable) { console.log(item); // undefined, undefined, undefined }Copy the code
- If the symbol. iterator method corresponds to anything other than an ergoer generator (that is, an ergoer object is returned), the interpretation engine will report an error.
var obj = {};
obj[Symbol.iterator] = () => 1;
[...obj] // TypeError: [] is not a function
Copy the code
The context in which the Iterator interface is called
- Deconstruction assignment
- An array and
Set
Is called by default when the structure is destructively assignedSymbol.iterator
Methods.
- An array and
- Extended operator
- Extended operator (
.
) will also call the defaultIterator
Interface.
- Extended operator (
yield*
yield*
This is followed by a traversable structure, which calls the traverser interface of that structure.
- other
for... of
,Array.from()
,Map(), Set()
.WeakMap()
.WeakSet()
(e.g.,new Map([['a',1],['b',2]])
),Promise.all()
,Promise.race()
.
Iterator object return() and throw()
- The traverser object in addition to having
next
Method can also havereturn
Methods andthrow
Methods. If you write your own traverser object generator function, thennext
Methods must be deployed,return
Methods andthrow
Whether or not a method is deployed is optional. for... of
The loop exits prematurely (usually because of an error, or there isbreak
Statement), will be calledreturn
Methods. If an object needs to clean up or release resources before completing traversal, it can be deployedreturn
Methods.
function readLinesSync(file) { return { [Symbol.iterator]() { return { next() { return { done: false }; }, return() { file.close(); return { done: true }; }}; }}; } for (let line of readLinesSync(fileName)) {console.log(line); break; } for (let line of readLinesSync(fileName)) {console.log(line); throw new Error(); }Copy the code
throw
The main method is to cooperateGenerator
Function, which we’ll see in the next pop.
for… Of circulation
- As a unified way to traverse all data structures.
- Compare with other traversals
for... of
Will correctly identify32
位UTF-16
Characters. With withfor... in
Same concise syntax, but nofor... in
Those flaws. Different from theforEach
Method, it can be withbreak
,continue
andreturn
Use together.
for (let x of 'a\uD83D\uDC0A') { console.log(x); } // 'a' // '\uD83D\uDC0A' Copy the code
forEach
Can’t jump out halfwayforEach
Cycle,break
Command orreturn
Orders are not effective.for... in
Looping disadvantages, one is that the array’s key name is a number, butfor... in
The loop has a string as its key name.0
“,”1
“,”2
“And so on. The second isfor... in
The loop iterates not only over numeric key names, but also over other manually added keys, and even keys on the prototype chain. And finally in some cases,for... in
The loop iterates over the key names in any order.for... in
Loops are designed primarily for traversing objects, not for traversing groups of numbers.
- Other types of data can be converted using other techniques
Iterator
Interface data structure reusefor... of
I’m going to iterate.- object
- use
Object.keys
The getKey () method generates an array of the object’s key names and then iterates through the array.
for (var key of Object.keys(someObject)) { console.log(key + ': ' + someObject[key]); } Copy the code
- use
Generator
The function rewraps the object.
function* entries(obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]]; } } for (let [key, value] of entries(obj)) { console.log(key, '->', value); } // a -> 1 // b -> 2 // c -> 3 Copy the code
- An array-like object but does not have one
Iterator
interface
- use
Array.from
Method to turn it into an array.
let arrayLike = { length: 2, 0: 'a', 1: 'b' }; For (let x of arrayLike) {console.log(x); } for (let x of array. from(arrayLike)) {console.log(x); }Copy the code