Promise is another asynchronous programming solution that is more reasonable and powerful than the callbacks + events approach we introduced earlier.
Promise’s task queue and priority
The callback event described in the previous article is to submit an asynchronous task to a human task queue for polling by the main thread
Promise also commits an asynchronous task to a task queue, but not a normal asynchronous task queue, but a microtask queue.
As opposed to a normal asynchronous event task queue which is a macro task queue,
So the same task list main thread polls the microtask list in a limited way
A microtask queue is a higher priority than a macro task queue
SetTimeout (()=>{console.log(' macro task list event)}) // Promise - new Promise((resolved, Reject) => {console.log('Promise') resolved(' microtask list event ')}). Then (value => {console.log(value)}) // Synchronize task Console. log(' sync event ')Copy the code
Therefore, the priority of asynchronous programming is divided into: synchronous task = synchronous task < micro task < macro task defined by Promise
The same synchronization tasks are performed in sequence
The macro task in Promise increases
It’s just a matter of knowing that within the Promise definition block is synchronized code, so when in the sync block
When a setTimeout() event is defined and the Promise state change is wrapped, the macro task executes before the microtask
Because the microtask has not yet been invoked in the list of microtasks
New Promise(resolved =>{setTimeout((=>{console.log(' asynchronous task ') resolved('Promise task ')})}). console.log(value) })Copy the code
Here the Promise task is executed only after the asynchronous task completes.
The basic syntax for promises
Here are two ways to write a Promise – a base definition and a wrapper definition
New Promise((resolve,reject) =>{resolve() reject()}).then(res=>{// successful callback}).catch(err=>{// failed callback}) // Encapsulate the definition function Promise(){ return new Promise((resolve,reject) => { resolve() reject() } })}Copy the code
The three states and singleness of the states of Promise
A Promise is simply a container that contains the result of an event that will happen or end in the future,
Promise is again an object that has three states
- Wait (pedding)
- Success (resolved)
- Failure state (Reject)
When there is no trigger, the state of the Promise is waiting. Once the trigger is triggered, the successful or failed state cannot be cancelled again, and the state is unique
** can ignore one of two states in a Promise,** responds to only one state, and then can be written forever
new Promise((resolve, reject)=>{
resolve()
reject()})
.then(null,res=>{
})
.then(null,res1=>{
})
Copy the code
Then is also a Promise
Then is a Promise, and the first THEN determines which one to execute based on whether the return succeeds or fails
The second THEN defaults to success, or the second THEN, if there is no Promise, is a chained function, with no Promise state response
A Promise corresponds to a then
Then (res=>{return '111'},null). Then (res1=>{sole.log(res1) // 111}) // Then new Promise(()=>{resolved()}). Then (res=>{return new Promise((resolved,reject)=>{reject(' error message ')})}) Then (null, (err) = > {the console. The log (err) / / error message})Copy the code
Error handling in promises
When a Promise state is REJECT, the second function of then is the callback that accepts the error message
New Promise((resolved, reject) =>{reject(' error ')}). Then (null,(err)=>{console.log(err) // Error})Copy the code
Another case where you don’t need to deal with specific THEN errors is when you can use a catch for unified processing, which means you can use a catch for multiple promises
New Promise((resolved, reject) => {reject(' error ')}). Then (res => {// normal processing status}). Catch (err => {// If no error callback is written Execute the uniform error callback function})Copy the code
So there are actually two states of error handling for a Promise, one is that the specific error handling is executed using the second argument to then, and once it’s executed it doesn’t go anywhere near the catch, right
The second is an error callback with no THEN, in which all error messages are summarized to catch execution
The use of the finally
Finally is a function that executes after a function executed with a success or failure callback. That is, when the Promise state changes from success to failure,finally will execute after them, no matter what the state is
New Promise ((resolve, reject) = > {reject (' failure ')}), then (res = > {}). The catch (err = > {}). The finally (() = > {})Copy the code
This can be done with loading state execution, which is invoked when a Promise asynchro is initiated and turned off when a Promise asynchro succeeds or the callback completes
Resolve to use
Resolve is an abbreviated form of the successful state of a Promise, which can return a successful state directly
Function query(){return promise.resolve (' successful state ')} Reject) => {resolve(' successful state ')})}Copy the code
Resolve is much more convenient than writing a full Promise
The use of reject
Like resolve,reject can return an error state directly, either as a callback in a specific function of THEN or as a catch
new Promise((resolve,reject) => {
})
.then(res => {
])
.catch(err => {
})
Copy the code
Promise. The use of all
The Promise.all interface can be used when multiple interfaces need to request together and obtain requirements for request data simultaneously
For example, if you have a requirement that you click on the TAB Food and attractions and we need to send the food and attractions data request together, use promise.all to accept it
Promise.all has two features
1. Successful callback is executed only when all all requests are successful
2. An error callback is executed when one of all Promise asynchronous operations fails
Promise. All ([request 1, 2]). Then (res = > {}). The catch (err = > {})Copy the code
We currently have this requirement: click the label button of food and scenic spot to synchronously obtain the data of these two requests, promise.all
Let tagArr = [' gourmet ',' tourist '] functon getTagdata(names){let Promise = names.map(val => {return ajax(' ${baseUrl}${value} ') }) return Promise(Promise) } getTagdata(tagArr) .then(res => { console.log(res) }) .catch(err => { console.log(err) }) .finally(()=>{// do some work after the data request})Copy the code
The use of Promise. AllSettled
Promise.allsettled and promise.all are similarly defined, except that promise.all will not execute a successful callback if one of the requests is settled in error
The Promise. AllSettled will be executed successfully even if there is a mistake. Only the array will be returned with “fulfilled” or “Rejected” status.
Promise.allsettled (promis).then(res => {// perform the operation})Copy the code
For example, if we request several requests and one request is in error, we still display the correct request and filter the incorrect request
Promise.allSettled(promis)
.then(res => {
res.filter(value => {
let successArray = value.status === 'fulfilled'
})
})
Copy the code
Promise. The use of the race
The syntax of promise. race is similar to that of promise. all, which is also multiple asynchronous operations, except that no matter how many asynchronous operations there are, promise. race returns only one result, which is a faster response to the request
Promise. Race ([' request event 1 ', '2' request events]), then (res = > {/ / success callback}). The catch (err = > callback} {/ / failure). The finally (() = > { Console. log(' promise.race completed ')})Copy the code
I usually use promise.race as the cut-off time for web requests
Function timeOut(delay){return new Promise((resolve, reject) => {setTimeout(() => {reject()) => {reject()) ')}, delay)})} Promise. Race ([ajax (' network request address), the timeOut (1000)]), then (res = > {the console. The log (res)}). The catch (err = > { The console. The log (err)}). The finally (() = > {the console. The log (' complete ')})Copy the code
The code race has two asynchronous operations, a network request and a timer. The timer is executed at a scheduled time
If the network request is not completed within the specified time, the timer task is executed to return that the network request has timed out.
Promise task queue
A Promise’s task queue is essentially the order in which Promise events are executed
General order of Promise execution
We can clearly know the execution order of a Promise by remembering one principle, that is, a Promise corresponds to a THEN and only after the first THEN is executed can the next Promise be executed
The new Promise ((resolve, reject) = > {} / / synchronization code), then (() = > {return Promise. The resolve ()}), then (() = > {/ / / execution})Copy the code
A chain of Promise tasks is generated
Use a map to encapsulate the Promise event execution order
The core idea encapsulated with a map is that there must be an advance Promise to execute, and a THEN is returned to execute subsequent results
For example, if you have two Promise events, use the event loop to make the Promise event chain
function qunue(num){
let promise = Promise.resolve()
num.map(v=> {
promise = promise.then(_ => {
return v()
})
})
}
funciotn fun1(){
return new Promise((resolve, reject) => {
setTimeout(_ => {
console.log('fun1')
},2000)
})
}
function fun2(){
return new Promise((resolve, reject) => {
setTimeout(_ => {
console.log('fun2')
},1000)
})
}
qunue([fun1,fun2])
Copy the code