Promise
1. Introduction
A promise is simply a container that holds the result of an event (usually an asynchronous operation) that will end in the future. Syntactically, a promise is an object from which to get messages for asynchronous operations. A promise is an object from which you can get messages for asynchronous operations. Promise provides a uniform API, and all kinds of asynchronous operations can be handled in the same way.
Characteristics of 2.
- The state of the promise object is independent of external influences. The Promise object represents an asynchronous operation and has three states: Pending, Resolved and Rejected. Only the result of an asynchronous operation can determine the current state, and no other operation can change the state. That’s where the name “promise” comes from. Its English name means “promise” and means nothing can change it
- Once the state changes, it never changes. You can get this at any time. The state of the Promise object can change from Pending to Resolved and from Pending to Rejected. As soon as those two things happen, the state is frozen and never changes, and the result will always be there, even if the change has already happened and you add a callback to the Promise object, you’ll get the result immediately. This is completely different from the event, where in particular, if you miss him, you can’t get results by listening again.
3. Usage
1. Simple usage
Var p = new Promise(function(resolve, reject){setTimeout(function(){console.log(' done '); Resolve (' whatever data '); }, 2000); });Copy the code
Promise’s constructor takes one argument, which is a function, and passes two arguments, resolve and reject, which represent the successful and unsuccessful callback of the asynchronous operation. In the code above, after 2s it prints “Execute complete” and calls the resolve method.
2. Why use promise instead of callback
Function runAsync(callback){setTimeout(function(){console.log(' done '); Callback (' whatever data '); }, 2000); } runAsync(function(data){ console.log(data); });Copy the code
Callback multi-layer nested maintenance reduced. You need to define a Callback2 and pass it to the callback. The advantage of Pomise is that you can continue writing the promise object in the THEN method and return it, and then continue calling the THEN for the callback.
3. Chain operation
function runAsync1(){ var p = new Promise(function(resolve, Reject){// do something async setTimeout(function(){console.log(' async task 1 completed '); Resolve (' whatever data 1'); }, 1000); }); return p; } function runAsync2(){ var p = new Promise(function(resolve, Reject){// do something async setTimeout(function(){console.log(' async task 2 completed '); Resolve (' whatever data 2'); }, 2000); }); return p; } function runAsync3(){ var p = new Promise(function(resolve, Reject){// do something async setTimeout(function(){console.log(' async task 3 completed '); Resolve (' whatever data 3'); }, 2000); }); return p; }Copy the code
runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return runAsync3();
})
.then(function(data){
console.log(data);
});
Copy the code
The output
Asynchronous task 1 Execute any data. 1 Asynchronous task 2 Execute any data. 2 Asynchronous task 3 Execute any dataCopy the code
In a Promise, the data is returned, which is called in the next THEN
In the THEN method, you can also return the data directly instead of the Promise object and then receive the data in the later THEN. For example, we can change the above code to look like this:
runAsync1() .then(function(data){ console.log(data); return runAsync2(); }) .then(function(data){ console.log(data); Return 'directly return data '; }). Then (function(data){console.log(data); });Copy the code
The output
Asynchronous task 1: Complete any data. Asynchronous task 2: Complete any data. 2: Return data directlyCopy the code
4. The method to reject
Used to catch a failed callback
function getNumber(){ var p = new Promise(function(resolve, Function (){var num = math.ceil (math.random ()*10); If (num<=5){resolve(num); } else{reject(' numbers are too large '); }}, 2000); }); return p; } getNumber() .then( function(data){ console.log('resolved'); console.log(data); }, function(reason, data){ console.log('rejected'); console.log(reason); });Copy the code
5. The usage of catch
A promise object has a catch method in addition to the then method. This, like the second argument to THEN, specifies the reject callback
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
Copy the code
Another use: specifies that the reject callback, when thrown, does not throw the JS, but instead enters the catch method
getNumber() .then(function(data){ console.log('resolved'); console.log(data); console.log(somedata); // someData undefined}). Catch (function(reason){console.log('rejected'); console.log(reason); });Copy the code
Because someData is undefined, if you don’t use promise, you’ll get an error and not run down. But here you get something like this
resolved
5
rejected
ReferenceError: somedata is not defined
at <anonymous>:5:17
at <anonymous>
Copy the code
6. All methods
Has parallelism capability and does not execute callbacks until all asynchronous operations have been executed
Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
console.log(results);
});
Copy the code
The data returned by the asynchronous operation is put into the array Results
The output
Asynchronous task 1 Execute Complete Asynchronous task 2 Execute Complete Asynchronous task 3 Execute complete (3) [" Any data 1", "any data 2"," Any data 3"]Copy the code
Application scenario: After loading static files such as images and Flash files, initialize the page
7. The use of the race
The effect of the all method is essentially “the slowest runner executes the callback,” as opposed to the “fastest runner executes the callback,” which is the race method, which is the word for race. Race is the same as all. Let’s change the runAsync1 delay to 1 second:
Promise
.race([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
console.log(results);
});
Copy the code
The execution result
Asynchronous task 1 Complete any data. 1 Asynchronous task 2 Complete Asynchronous task 3 CompleteCopy the code
Application scenario: For example, we can use race to set a timeout for an asynchronous request, and then execute the corresponding operation after the timeout, the code is as follows:
Function requestImg(){var p = new Promise(function(resolve, reject){var img = new Image(); img.onload = function(){ resolve(img); } img.src = 'xxxxxx'; }); return p; } // Delay function, Function timeout(){var p = new Promise(function(resolve, reject){setTimeout(function(){reject(' reject '); }, 5000); }); return p; } Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(reason){ console.log(reason); });Copy the code
The requestImg function will asynchronously request an image, and I’ll write the address as “XXXXXX”, so it will definitely fail. The timeout function is an asynchronous operation with a delay of 5 seconds. We put the two functions that return the Promise object into race, and they race. If the image request is successful within 5 seconds, then the normal process is followed. If the image is not returned within 5 seconds, timeout wins and a catch message is displayed indicating that the image request has timed out. The running results are as follows:
8.Promise.resolve
The promise.resolve (value) method returns a resolved Promise object with a fixed value. If a promise is returned, a Promise is returned; If the value is a Thenable, the returned promise will “follow” the thenable object and adopt its final state. Otherwise the returned promise will be fulfilled with this value
const p1 = Promise.resolve(123)
p1.then((value) =>{
console.log(value)//123
})
//equle
const p1 = new Promise((resolve,reject)=>{
resolve(123)
})
p1.then((value)=>{
console.log(value)//123
})
Copy the code
Promise.resolve() and resolve
- Promise.resolve(thenable) and resolve(thenable) have different processing results
new Promise((resolve)=>{
resolve(thenable)
//eq
Promise.resolve().then(()=>{
thenable.then(()=>{
})
})
}).then(()=>{
thenable
})
Copy the code
- Promise.resolve(non-thenable) and resolve(non-thenable) have the same processing result
//let resolvePromise = new Promise(resolve => {
//resolve('str')
//})
//works like
let resolvePromise = Promise.resolve('str')
Copy the code
async and await
Introduction to the
Async functions are functions declared using the async keyword. Async functions are instances of AsyncFunction constructors and allow the await keyword. The async and await keywords allow us to write asynchronous behavior based on promises in a more concise way, without the need to intentionally chain calls to promises
features
- The await keyword value is valid within an async function and an error will be reported if it is used outside an async function
- The purpose of async/await is to simplify the use of promises
- Await expressions suspend the execution of the entire async function and give it control, resuming the process only after the promise-based asynchronous operation it is waiting for has been fulfilled or rejected. The settlement value of the promise is treated as the return value of the await expression.
- Async functions must return a Promise object. If an async function returns a value that does not appear to be a promise, it will be wrapped implicitly in a Promise
async function foo(){
return 1;
}
//equal
function foo () {
return Promise.resolve(1)
}
Copy the code
async function foo() {
await 1
}
//equal
function foo() {
return Promise.resolve(1).then(() => undefined)
}
Copy the code
- The code after the await expression can be considered to be in the THEN callback of the chained call. Multiple await expressions will be added to the then callback of the chained call, and the return value will be the return value of the last THEN callback
Promise and Async classic interview questions
Async function async1() {console.log('async1 start') await async2() console.log('async1 end') // version 2 bChrome 73 // new Promise((resolve)=>{// console.log('2') // resolve(); // }).then(()=>{ // console.log('1 end') // }) // or // Promise.resolve(console.log(2)).then(() => { // console.log('1 Resolve (resolvedPromise) works like // promise.resolve ().then(() => resolvedPromise.then(resolve, reject)); // Promise.resolve(console.log(2)).then(() => { // Promise.resolve().then(() => { // }) // }).then(()=>{ // console.log('1 end') // }) } async function async2() { console.log('async2') } console.log('script start') setTimeout(function() { console.log('setTimeout') }, 0) async1() new Promise(function(resolve) { console.log('promise1') resolve() }).then(function() { console.log('promise2') }) console.log('script end')Copy the code
You don’t know javascript supplement
- Sometimes a task is completed simultaneously and sometimes asynchronously, which can lead to race conditions. According to the promise definition, you don’t have to worry about this, because even promises that are completed immediately cannot be observed synchronously.
- Call too late
p.then(function () { p.then(function() { console.log('c'); }) console.log('a')}) p.chen (function () {console.log('b')}) ABC //c can't interrupt or preempt B, because that's how promise worksCopy the code
After a promise is resolved, all callbacks registered by THEN () on that promise are immediately called, in turn, at the next asynchronous timing point. None of these callbacks can affect or delay calls to other callbacks
- Promise scheduling technique
var p3 = new Promise(function (resolve,reject) { resolve('b'); }) var p1 = new Promise(function (resolve,reject) { resolve(p3) }) var p2 = new Promise(function (resolve,reject) { Resolve ('a')}) p1.then(function (v) {console.log(v)}) p2.then(function (v) {console.log(v)}Copy the code
Instead of an immediate value, P1 is resolved with another promise P3, which itself resolves to a value of ‘b’, and the stated action is to expand P3 to P1, but asynchronously. So in the asynchronous task queue, the p1 callback is ranked after the P2 callback