The basic part mainly introduces the basic use methods and characteristics of Promise, and the advanced part talks about the complex use of Promise.
Promise chain and Promise composite
Promise chain
Since each Promise instance returns a new Promise object, and the returned Promise object has its own instance method, the method of the returned Promise instance is called to generate a new Promise object, and then its method is called. This concatenated method call is the Promise chain.
function delayedExecute(str, callback = null) {
setTimeout(() = > {
console.log(str)
callback && callback()
}, 1000)
}
delayedExecute('p1 callback'.() = > {
delayedExecute('p2 callback'.() = > {
delayedExecute('p3 callback'.() = > {
delayedExecute('p4 callback'.() = >{})})})// p1 callback (1 second later)
// p2 callback (2 seconds later)
// p3 callback (3 seconds later)
// p4 callback (4 seconds later)
Copy the code
Use Promise chains to solve this callback-dependent hell problem:
function delayedExecute(str) {
return new Promise((resolve, reject) = > {
console.log(str)
setTimeout(resolve, 1000)
})
}
delayedExecute('p1 excutor')
.then(() = > delayedExecute('p2 excutor'))
.then(() = > delayedExecute('p3 excutor'))
.then(() = > delayedExecute('p4 excutor'))
// p1 excutor (1 SEC later)
// p2 excutor (2 seconds later)
// p3 excutor (3 seconds later)
// p4 excutor (4 seconds later)
Copy the code
Promise figure
Because a Promise can have multiple handlers, Promise chains can build directed acyclic graph structures. Each Promise instance is a vertex along the way, and handlers added using the instance method are directed vertices. Because each node in the diagram waits for the previous node to settle, the direction of the diagram is the order in which promises are resolved or rejected.
Here’s a Promise to represent a Promise digraph, or binary tree:
// A
/ / / /
// B C
// / \ /
// D E F G
let A = new Promise(resolve= > {
console.log('A')
resolve()
})
let B = A.then(() = > console.log('B'))
let C = A.then(() = > console.log('C'))
B.then(() = > console.log('D'))
B.then(() = > console.log('E'))
C.then(() = > console.log('F'))
C.then(() = > console.log('G'))
// A
// B
// C
// D
// E
// F
// G
Copy the code
The Promise chain represents a binary tree because Promise handlers are added to the message queue and then executed one by one, thus forming a sequential traversal of the binary tree.
Promise.all()
This static method takes an iterable and returns a new Promise object, also known as a synthetic Promise object.
Syntax: promise. all([arg1, arg2… )
Features:
-
The elements in the iterable are converted to a Promise object via promise.resolve ().
-
An empty iterable is equivalent to promise.resolve ().
-
Not passing in an iterable throws a type error.
-
The synthesized object is resolved:
- Only when iterable
all
Elements of thePromise
Objects areresolved
The composite object willresolved
. - Synthesized object
resolvedResult
All values arePromise
The object’sresolvedResult
And the order of the array is the order of the elements in the iterable.
- Only when iterable
-
The synthesized object is in a pending state:
As long as one of the iterable’s elements is in a pending state, the synthesized object’s state is pending.
-
The synthesized object is in the Rejected state:
- As long as there are elements in the iterable
A Promise
The object isrejected
State, then the state of the synthesized object isrejected
. - Synthesized object
rejectedResult
The value isThe first Rejected object
therejectedResult
. - behind
The rejected Promise object
Will not affect therejected
Of the composite objectrejectedResult
Value. - synthetic
Promise
Object silently handles all containmentrejected
thePromise
Object operations,That is, no more exceptions are thrown
.
let p1 = Promise.all([ Promise.reject(1), new Promise((null, reject) = > { setTimeout(reject, 0.2)})])let p2 = p1.catch(err= > { console.log(err) / / 1 }) console.log(p1) // Promise <rejected>: 1 console.log(p2) // Promise <fulfilled>: undefined Copy the code
- As long as there are elements in the iterable
Promise.race()
This static method takes an iterable and returns a new Promise object, also known as a wrapped Promise object, which is the first Promise mirror in a set of collections to resolve h or reject.
Features:
- Elements in the iterable pass through
Promise.resolve()
convertPromise
Object. - An empty iterable is equivalent to
new Promise(() => {})
. - Incoming non-iterable objects are thrown
TypeError
. Promise.race()
It’s a game, as the name suggests, onlyThe first one
We get to a settled state(Pending -> resolved or pending -> Rejected)
thePromise
Objects are wrapped asResults the Promise
. Whatever the first state isresolved
orrejected
, the rest of the rest will be ignored. If the first resting state is zerorejected
And the others in the backrejected
States are handled silently and no exceptions are thrown.
Serial Promise synthesis
Concatenating Promise objects based on subsequent Promise objects using the return values of previous Promise objects is a basic Promise function.
function addTwo(x) {
return x + 2
}
function addThree(x) {
return x + 3
}
function addFive(x) {
return x + 5
}
//
function addTen_1(x) {
return addFive(addThree(addTwo(x)))
}
/ / use the Promise
function addTen_2(x) {
return Promise.resolve(x)
.then(addTwo)
.then(addThree)
.then(addFive)
}
// Use Promise and array.prototype.reduce ()
function addTen_3(x) {
return [addTwo, addThree, addFive].reduce((promise, fn) = > promise.then(fn), Promise.resolve(x))
}
// Extract generic functions
fucntion compose(. fns) {
return (x) = > fnx.reduce((promise, fn) = > promise.then(fn), Promise.resolve(x))
}
Copy the code
Promise to expand
Promise to cancel
class CancelToken {
constructor(cancelFn) {
this.promise = new Promise((resolve, reject) = > {
cancelFn(() = > {
setTimeout(console.log, 0.'delay cancelled')
resolve()
})
})
}
}
const startBtn = document.getElementById('start')
const cancelBtn = document.getElementById('cancel')
function cancellableDelayedResolve(delay) {
setTimeout(console.log, 0.'set delay')
return new Promise((resolve, reject) = > {
const id = setTimeout((() = > {
setTimeout(console.log, 0.'delay resolve')
resolve()
}), delay)
const cancelToken = new CancelToken(cancelCallback= > cancelBtn.addEventListener('click', cancelCallback))
cancelToken.promise.then(() = > clearTimeout(id))
})
}
startBtn.addEventListener('click'.() = > cancellableDelayedResolve)
Copy the code