Promise
features
Create an instance
One: created using a constructor, which accepts a callback function that passes in the resolve and reject methods
const promise = new Promise((resolve, reject) = > {
resolve('data')
})
promise.then((data) = > {
console.log(data) // data, then print
})
console.log(promise instanceof Promise) // true, print first
Copy the code
The advantage of this approach is that it is flexible and allows you to control the additional actions you can take when creating a Promise instance, but the code is cumbersome
The code executes the constructor synchronously, and only asynchronously when it starts the chain call
Two: create using static methods promise.resolve () or promise.reject ()
const promise = Promise.resolve('data')
promise.then((data) = > {
console.log(data) // data
})
Copy the code
Promise.resolve() is the syntactic sugar of new Promise((resolve) => {resolve()}), and does exactly the same thing
During the chain invocation of a Promise, each chain invocation of a chained method (resolve, Reject, THEN, Catch, finally) returns a brand new Promise instance, so this method can naturally be used as a Promise creation
Declare that the instance is a synchronous operation, and the asynchronous task will only be created when the chain call is initiated
const promise = new Promise((resolve) = > {
resolve('promise')})const promiseTask = promise.then(() = > 'promiseTask')
console.log('Synchronization task starts..... ')
console.log('promise:')
console.log(promise)
console.log('promiseTask:')
console.log(promiseTask)
setTimeout(() = > {
console.log('Asynchronous task starts..... ')
console.log('promise:')
console.log(promise)
console.log('promiseTask:')
console.log(promiseTask)
})
Copy the code
State changes
Promise has three states:
- Pending: Pending
- Resolved: Resolved (also known as Resolved
fulfilled
) - Rejected: It has failed
There are only two types of state changes:
- Pending → Resolved
- Pending → Rejected
When a promise state passes from pengding to another arbitrary state, the promise state remains in that state and cannot be changed
If no errors occur in chain calls, they are all pending → Resolved state transitions
Asynchronous blocking
In a chained call to a promise, the state of the previous promise is set to non-pending before the next promise is executed. Note that blocking only works for promises and does not directly apply to other asynchronous functions
Promise.resolve()
.then(() = > {
setTimeout(() = > {
console.log('setTimeout method executed')
})
})
.then(() = > {
console.log('Mission completed')})Copy the code
If you want to block these tasks you need to encapsulate them with promises
Promise.resolve()
.then(() = > {
return new Promise((resolve) = > {
setTimeout(() = > {
console.log('setTimeout method executed')
resolve()
})
})
})
.then(() = > {
console.log('Mission completed')})Copy the code
The data transfer
The data delivery of a promise can only accept the previous data by the next chain call, not across levels
Promise.resolve('A')
.then((data) = > {
console.log(data) // A
return 'B'
})
.then((data) = > {
console.log(data) // B
})
Copy the code
The then callback uses return to pass the result, whereas Promise passes resolve because the compiler resolves the value of return in then to return promise.resolve (…). “Returns a new promise instance
Error handling
Promise uses reject and catch to catch errors
The Reject method returns a promise of a failed state, which is used to throw an error
const promise = Promise.resolve().then(() = > {
return new Promise((resolve, reject) = > {
reject('Big deal!! ')})})console.log(promise)
setTimeout(() = > {
console.log(promise)
})
Copy the code
The catch method returns a promise of success status, which is used to handle errors
const promise = Promise.resolve().then(() = > {
throw new Error('Big deal!! ')
})
.catch((err) = > {
console.log(err)
return 'Error message'
})
console.log(promise)
setTimeout(() = > {
console.log(promise)
})
Copy the code
Association relation:
- After the previous promise is set to reject, its data is passed to the second callback of the next THEN method. If the callback is not declared, the data is captured by the subsequent catch method
- If the error is caused by a network, the error can only be caught by a catch
So we usually just use the catch method
const promise = Promise.reject('Big deal!! ')
.then(
(data) = > {console.log(data)}, // No data is printed
(err) = > {console.log(err)} // Something is wrong!!
)
Copy the code
const promise = Promise.reject('Big deal!! ')
.then(
(data) = > {},
(err) = > {}
)
.catch((err) = > {
console.log(err) // No data is printed because the error was caught earlier
})
Copy the code
Processing order: If one of the promises is put in a failed state, the promise task before the error is caught will not be executed
// > tasks 3, 4 will not be executed, using the second callback function of then to catch the same error function
Promise.resolve()
.then(() = > {console.log('Perform the first task')})
.then(() = > {
console.log('Perform the second mission')
throw new Error('Big deal!! ')
})
.then(() = > {console.log('Perform the third mission')})
.then(() = > {console.log('Run the fourth mission')})
.catch((err) = > {
console.log('Run the fifth mission')
console.log(err)
})
.then(() = > {console.log('Run the sixth mission')})
Copy the code
If there are more than one error, then catch the error → catch the first error in the process
Promise.reject('Big deal!! ')
.then(() = > {
throw new Error('Big deal again!! ')
})
.catch((err) = > {
console.log(err) // Something is wrong!!
})
.catch((err) = > {
console.log(err) // No data is printed
})
.then(() = > {
throw new Error('Big deal again!! ')
})
.catch((err) = > {
console.log(err) // Again big trouble!!
})
Copy the code
Promise method
Chain calls
promise.then (callback? , errorCallback?)
- Function: Chain calls the next task
- Parameters:
callback? : function(data)
:- Data: Data passed when the last promise was successful
errorCallback? : function(error)
:- Error:
Error → catch
The initial mistake in the process
- Error:
- The return value:
Promise
: Returns a new promise
Promise.resolve('Data passed')
.then((data) = > {
console.log(data) // The data passed
})
.then((data) = > {
console.log(data) // undefined because the previous promise did not pass a value
})
Copy the code
promise.catch (callback?)
- Function: Catch errors during chained tasks
- Parameters:
callback? : function(error)
:- Error:
Error → catch
The initial mistake in the process
- Error:
- The return value:
Promise
: Returns a new promise
Promise.reject('Big deal!! ')
.catch((err) = > {
console.log(err) // Something is wrong!!
})
Copy the code
promise.finally (callback?)
- Function: Executes this method regardless of whether there is an error in the task chain
- Parameters:
callback? : function()
: Execution content
- The return value:
Promise
: Returns a new promise
new Promise((resolve, reject) = > {
resolve()
})
.then(() = > new Promise((resolve, reject) = > {
reject()
}))
.finally(() = > {
console.log('Mission accomplished') // Mission completed
})
Copy the code
Parallel processing
Promise.all (promiseTasks)
- Function: Parallel processing of multiple promise tasks, only all promises are successful promise returned will be successful, otherwise fail
- On success, the data from each promise is stored in an array in the order of the task declaration and passed to the next promise
- When it fails, the first failed promise error message is passed to the next promise
- Parameters:
promiseTasks: Array<Promise>
: PROMISE Task set
- The return value:
Promise
: Returns a new promise that contains an array of data for all successful tasks, or information about the first failed task
Each promise is independent during parallel processing, so the failure of one promise does not affect other promises, only the outcome of the parallel function
// > Print 1, 5, and 10 sequentially, indicating that the tasks are processed in parallel
const delay = (time, callback) = > new Promise((resolve) = > {
setTimeout(() = > {
callback()
resolve(time)
}, time)
})
const result = Promise.all([
delay(10.() = > {console.log(10)}),
delay(1.() = > {console.log(1)}),
delay(5.() = > {console.log(5)}),
])
result.then((data) = > {
console.log(data) // [10, 1, 5]
})
Copy the code
Promise.all blocks all tasks on success until all tasks succeed, but if any task fails, it immediately jumps out of the method and proceeds down the chain. (This does not affect the continuation of the Promise task set within promise.all)
// > Order print big things!! 1, 5, 10, indicating that promise. all immediately exits the chain call to the next task when it fails
const result = Promise.all([
delay(10.() = > {console.log(10)}),
delay(1.() = > {console.log(1)}),
Promise.reject('Big deal!! '),
delay(5.() = > {console.log(5)}),
Promise.reject('Big deal again!! '),
])
result.then(
() = > {},
(err) = > {console.log(err)} // Something big has happened!!
)
Copy the code
Promise.race (promiseTasks)
- Function: Handle multiple promise tasks in parallel. If one promise is not in a pengding state, it will immediately jump out of the method and go down the chain. (Other tasks that are still being executed will not be interrupted and continue to be executed.)
- Parameters:
promiseTasks: Array<Promise>
: PROMISE Task set
- The return value:
Promise
: Returns a new promise, passing data for the first successful or failed task
// > Print 1, 5, and 10 sequentially
const delay = (time, callback) = > new Promise((resolve) = > {
setTimeout(() = > {
callback()
resolve(time)
}, time)
})
const result = Promise.race([
delay(10.() = > {console.log(10)}),
delay(1.() = > {console.log(1)}),
delay(5.() = > {console.log(5)}),
])
result.then((data) = > {
console.log(data) / / 1
})
Copy the code
Promise.allSettled (promiseTasks)
- Function: Handles multiple promise tasks in parallel, and only if all promises are in a non-penging state will the call continue down the chain
- Parameters:
promiseTasks: Array<Promise>
: PROMISE Task set
- The return value:
Promise
: Returns a new Promise, passing all promise task information
// > Print 1, 5, and 10 sequentially
const delay = (time, callback) = > new Promise((resolve) = > {
setTimeout(() = > {
callback()
resolve(time)
}, time)
})
const result = Promise.allSettled([
delay(10.() = > {console.log(10)}),
delay(1.() = > {console.log(1)}),
Promise.reject('Big deal!! '),
delay(5.() = > {console.log(5)}),
Promise.reject('Big deal again!! '),
])
result.then((data) = > {
console.log(data)
})
Copy the code
Use skills
The time delay function
Making a delay function with promise can be placed in the Promise task chain or async function to block asynchronous operations
// Print 1, 2, 3 sequentially
const delay = (time, callback) = > new Promise((resolve) = > {
setTimeout(() = > {
callback()
resolve()
}, time)
})
const fn = async() = > {console.log(1)
await delay(50.() = > {console.log(2)})
console.log(3)
}
fn()
Copy the code
Timeout handling
The promise.race feature allows you to make a timeout handler, often used in network request timeouts
Native Promises cannot cancel or interrupt a task in progress directly, but can only prevent the delivery of data by reporting an error
// Print 1, 2, 3 sequentially
const delay = (time, callback) = > new Promise((resolve) = > {
setTimeout(() = > {
callback()
resolve()
}, time)
})
Promise.race([
delay(500.() = > {console.log(End of request)}), // The simulated request takes 500ms
delay(300.() = > {throw new Error('Request timed out')})])Copy the code