Promise
After learning Ajax, I still had a shallow understanding of asynchronous requests. After learning Promise, I also had a deeper understanding of asynchronous calls
Promises are a solution to asynchronous programming. When you send multiple Ajax requests, they return data in a different order than when they were sent (request times are different).
Distinguish instance objects from function objects
-
Function object: When used as an object, a function is simply called a function object
-
Instance objects: Objects generated by the new function, simply called objects
Classification of callback functions
-
Example: Array traversal of the associated callback function/Promise’s excutor function
// 1. Synchronize the callback function const arr = [1.3.5] arr.forEach(item= > { console.log(item); }) console.log('the forEach ()'); Copy the code
-
An asynchronous callback: understand: not executed immediately, can be carried in the future in the callback queue example: timer callback/ajax callback/Promise success | failure callback
// 2. Asynchronous callback function setTimeout(() = > { console.log('timerout'); // Async callbacks are queued }, 0) console.log('the setTimeout () before'); Copy the code
-
Error TypeError: the parent type of all errors ReferenceError: the referenced variable does not exist TypeError: the data type is incorrect RangeError: the data value is not in the allowed range SyntaxError: SyntaxError
// Common built-in errors // 1) ReferenceError: The referenced variable does not exist console.log(a); console.log('-- -- -- -- -- -- --); // The following code will not execute without catching error Copy the code
-
Catch error: try… catch
// Catch an error try { let b; console.log(b.xxx); } catch (error) { console.log(error.message); console.log(error.stack); } Copy the code
Throw error: Throw error
// Throw an error function sth() { if (Date.now() % 2= = =1) { console.log('Current task is odd, can be executed'); } else { // If an exception occurs, it is handled by the caller throw new Error('Current events are even, cannot be executed'); }}// Catch and handle exceptions try { sth(); } catch (error) { console.log(error.message); } Copy the code
-
Error object Message property: error related information Stack property: function call stack records
// Common built-in errors
// 1) ReferenceError: The referenced variable does not exist
console.log(a);
console.log('-- -- -- -- -- -- --); // The following code will not execute without catching error
Copy the code
1.1 Basic use of Promise
A. Abstract expression
Promise is a new solution for asynchronous programming in JS (the old one was pure callbacks)
B
- Syntactically: Promise is a constructor
- Functionally: The Promise object encapsulates an asynchronous operation and can retrieve its results
1. Create a new Promise object
const p = new Promise((resolve, reject) = > {// The actuator function synchronizes the callback
console.log('execution excutor')
// 2. Perform asynchronous operations
setTimeout(() = > {
const time = Date.now() // If the current time is even, success is achieved; otherwise, failure is achieved
If successful, call resolve(value)
if (time % 2= =0) {
resolve('Successful data, time=' + time)
} else {
If this fails, call reject(reason)
reject('Failed data, time=' + time)
}
}, 1000);
})
console.log('New Promise() after')
// setTimeout(() => {
p.then(
value= > { // Successfully receive value data onResolved
console.log('Successful callback', value)
},
reason= > {// Receive the failed Reason data onRejected
console.log('Failed callback', reason)
}
)
// }, 2000);
Copy the code
-
The way to specify callbacks is more flexible: Old: Promise must be specified before an asynchronous task is started: Start an asynchronous task => return a Promise object => Bind a callback to a Promise object (you can even specify it after the asynchronous task ends)
-
Support for chained calls to solve the problem of callback hell what is callback hell? Callback function nested calls, external callback function asynchronous execution results in nested callback function execution of conditional callback hell disadvantage? Not easy to read/not easy exception handling solution? Promise chain call ultimate solution? async/await
/* Callback hell */
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult)
}, failureCallback)
}, failureCallback)
}, failureCallback)
/* Use Promise's chained calls to solve callback hell */
doSomething()
.then(function (result) {
return doSomethingElse(result)
})
.then(function (newResult) {
return doThirdThing(newResult)
})
.then(function (finalResult) {
console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback) // Any exceptions that occur are passed in here
/* async/await: the ultimate solution to callback hell */
async function request() {
try {
const result = await doSomething()
const newResult = await doSomethingElse(result)
const finalResult = await doThirdThing(newResult)
console.log('Got the final result: ' + finalResult)
} catch (error) {
failureCallback(error)
}
}
Copy the code
1.2 State changes of Promise
-
Pending to resolved
-
Pending a rejected
Note: There are only two types, and the promise object can only change once
Success or failure, there will be a result data
The result data for success is usually called value, and the result data for failure is usually called Reason
1.3 Basic process of Promise
2.1 PromiseAPI
- The Promise constructor: Promise (
excutor
) {}excutor
Function: synchronous execution (resolve, reject) => {} Resolve function: internal definition success we call value => {} reject function: internal definition failure we call reason => {} Description:excutor
The callback is immediately synchronized within the Promise, and the asynchronous operation is performed in the executor Promise.prototype.then
Methods: (onResolved, onRejected
) = > {}OnResolved function
: Successful callback function (value) => {}onRejected
Function: failed callback (reason) => {} Description: Specifying the success callback used to get a successful value and the failure callback used to get a failed reason returns a new Promise objectPromise.prototype.catch
Methods: (onRejected
) = > {}onRejected
Function: failed callback (reason) => {}onRejected
)Promise.resolve
(value) => {} value: successful data or promise object Description: Return a successful/failed PROMISE objectPromise.reject
(reason) => {} Reason: return a failed PROMISE objectPromise.all
(promises) => {} Promises: promises nAn array ofNote: Return a new promise, which succeeds only if all promises succeed, or if one failsPromise.race
Methods: (1) promises) = > {} promises: array containing n promise: return a new promise, the first promise to complete the results of the state is the final result
new Promise((resolve, reject) = > { setTimeout(() = > { // resolve(' resolve ') reject(' error ')}, 1000)}). Then (value => {console.log('onResolved()1', value) }).catch( reason => { console.log('onRejected()1', Const p1 = new promise ((resolve, reject) => {setTimeout(() => {resolve(1)}, 100); })const p2 = Promise.resolve(2)const p3 = Promise.reject(3)// p1.then(value => { console.log(value) })// p2.then(value => { console.log(value) })// p3.catch(reason => { console.log(reason) })// const pAll = Promise.all([p1, p2, p3])const pAll = Promise.all([p1, p2])pAll.then( values => { console.log('all onResolved()', values) }, reason => { console.log('all onRejected()', reason) })const pRace = Promise.race([p1, p2, p3])pRace.then( value => { console.log('race onResolved()', value) }, reason => { console.log('race onRejected()', reason) })
Copy the code
2.2 Some problems with Promises
1. How to change the state of promise?
Resolve (value): resolved (2)reject(reason): rejected (3) Resolve (value): resolved (2) Reject (reason): rejected (3) If it is pending, it changes to Rejected
let p = new Promise((resolve, reject) = > { //resolve('Promise 'is resolved') // reject('Promise' is rejected') throw new Error('Promise 'is rejected')}
Copy the code
2. Will multiple success/failure callbacks specified by a promise be called?
This is called whenever a promise changes to the corresponding state
let p = new Promise((resolve, reject) = > { throw 3; });Value => {console.log('value1', value)}, reason => {console.log('reason1', value) reason) // reason1 3 })p.then( value => { console.log('value2', value) }, reason => { console.log('reason2', reason) // reason2 3 })
Copy the code
3. Which comes first, changing the promise state or specifying the callback function?
(1) Both are possible. The normal case is to specify the callback and then change the state, but it is also possible to change the state and then specify the callback
(2) How to change the state before specifying the callback?
Resolve ()/reject()
Then ()
(3) When will the data be available?
If the callback is specified first, the callback function will be called when the state changes, and the data will be returned
② If the state is changed first, the callback function will be called when the callback is specified
/ / routine: New Promise((resolve, reject) => {setTimeout(() => {resolve(1) // async callback)}, 1000); Value => {}, reason => {console.log('reason', reason)}) New Promise((resolve, reject) => {resolve(1)}). Then ((resolve, reject) => {resolve(1)}). Then is executed synchronously, specifying the callback function synchronously. Value => {console.log('value2', value)}, reason => {console.log('reason2', value) "Reason)}) console. The log (' -- -- -- -- -- - ') / / the second const p = new Promise ((resolve, Reject) => {setTimeout(() => {resolve(1) // state change (specify data), async callback function}, 1000); })setTimeout(() => { p.then( value => { console.log('value3', value) }, reason => { console.log('reason3', reason) } )}, 1100);
Copy the code
4. promise.then()
What determines the result state of a new promise returned?
Then () specifies the result of the callback function execution. When the promise is resolved and value is resolved, the new promise will be resolved and value will be resolved. When the promise is resolved, the new promise will be resolved and value will be resolved. The result of this promise becomes the result of the new promise
new Promise((resolve, reject) = > { Resolve (1) reject(1)}).then(value => {console.log('onResolved1()', value)) // return Promise. Resolve (3) // return Promise. Reject (4) throw 5} reason => { console.log('onRejected1()', reason) // 1 // return 2 // return Promise.resolve(3) // return Promise.reject(4) throw 5 }).then( value => { console.log('onResolved2()', value) // 5 }, reason => { console.log('onRejected2()', reason) })
Copy the code
5. How does promise string together multiple action tasks?
(1) Promise’s then() returns a new promise, which can be opened as a chain call to then()
(2) Chain multiple synchronous/asynchronous tasks through chaining calls to THEN
new Promise((resolve, reject) = > { setTimeout(() = > { console.log("Perform Task 1(asynchronous)") resolve(1)},1000); }).then(value= > { console.log(Result of Task 1:, value) console.log('Perform Task 2(Synchronize)') return 2 }).then( value= > { console.log(Result of Task 2:, value) return new Promise((resolve, reject) = > { / / start the task 3 (asynchronous) setTimeout () = > {the console. The log (' mission 3 (asynchronous))) resolve (3)}, 1000); })}). Then (value = > {the console. The log (' the result of task 3: 'value)}) / / execution results:
Copy the code
6. Promise exception passthrough?
(1) When using promise’s then chain call, you can specify the failed callback at the end,
(2) Any previous operation out of the exception, will be transmitted to the final failed callback processing
7. Break the Promise chain?
(1) When using promise’s then chain call, it breaks in the middle and does not call subsequent callback functions
(2) Method: Return a Promise object in a pending state in the callback function
new Promise((resolve, reject) = > { // resolve(1) reject(1)}).then( value => { console.log('onResolved1()', value) return 2 }, Then (value => {console.log('onResolved2()', value) return 3}, reason => { throw reason }).then( value => { console.log('onResolved3()', value) }, reason => Promise.reject(reason)).catch(reason => { console.log('onReejected1()', // throw reason // return promise. reject(reason) /* add: */ return new Promise(() => {}) // Return a pending Promise interrupt the Promise chain}). Then () value => { console.log('onResolved3()', value) }, reason => { console.log('onReejected2()', reason) })
Copy the code
3. Macro and microqueues
- Macro queue: Used to hold macro tasks (callbacks) to be executed, such as timer callbacks /DOM event callbacks
ajax
The callback - Microqueue: Used to hold microtasks (callbacks) to be executed, such as promise’s callbacks
MutationObserver
The callback JS
Execution distinguishes between the two queuesJS
The engine must first perform all the initial synchronization tasks before the code is ready to pull out the first macro task to execute all the microtasks one by one
setTimeout(() = > { Console.log ('setTimeout1') promise.resolve (3).then(value => {console.log('onResolved3', value)})}, 0)setTimeout(() => { console.log('setTimeout2')}, 1) promise.resolve (1). Then (value => {console.log('onResolved1', value) })Promise.resolve(2).then(value => { console.log('onResolved2', Value)})// Browser result /* onResolved1 1 onResolved2 2 setTimeout1 onResolved3 3 setTimeout2 */
Copy the code
We may have a deeper understanding of macro queue and microqueue in future applications. I was shocked by the powerful function of Promise in the process of learning promise. Axios is also a library encapsulated with promise. Provides a lot of convenience for us to send asynchronous requests ~