One, foreword
Q: What is it? What to do? How to do?
-
What is? —-Promise is a solution to asynchronous programming, a new object added to ES6 to deliver messages for asynchronous operations. It represents some event (usually an asynchronous operation) whose outcome is known in the future, and it provides a uniform API for further processing.
-
What to do? —-Promise solves the problem of callback hell. In multiple nested callback methods, if there are synchronous and asynchronous methods at the same time, the actual execution order will be chaotic, which is not easy to debug and maintain.
-
How to do? 3.1 Suppose there is a requirement that when connecting to the server interface, it wants to get the data5 returned by the interface URL of ‘URL5’, but URL5 needs the data returned by URL4 as the parameter, urL4 needs the data returned by URL3 as the parameter, and so on. (The nesting level is slightly exaggerated. However, in actual development, it is often the case that the data returned by the previous interface is passed as the parameters of the next interface.
$.get('/url1'.function (data1) { $.get('/url2', data1, function (data2) { $.get('/url3', data2, function (data3) { $.get('/url4', data3, function (data4) { $.get('/url5', data4, function (data5) { console.log(data5) }) }) }) }) }) Copy the code
Use the Promise solution:
let promise = new Promise((resolve, reject) = > { $.get('/url1'.data1= > { resolve(data1) }) }) promise.then((data1) = > { $.get('/url2', data1, data2= > { return data2 }) }).then((data2) = > { $.get('/url3', data2, data3= > { return data3 }) }).then((data3) = > { $.get('/url4', data3, data4= > { console.log(data4) }) }) Copy the code
Second, Promise use principle analysis
Promise
It’s a class, and when you execute that class, you have to pass in an executor, and the executor executes immediatelyPromise
There are three states, which are waitingpending
That successfulfilled
, failurerejected
pending
->fulfilled
pending
->rejected
Once the status is determined, it cannot be changedresolve
andreject
Functions are used to change stateresolve
:fulfilled
reject
:rejected
then
What the method does internally is it determines the state and if the state is success it calls the successful callback and if the state is failure it calls the failed callbackthen
Methods are defined in the prototype objectthen
The success callback takes one parameter to indicate the value after successthen
Failure to call back a parameter, indicating the cause of the failure
Third, write Pormise
- create
Mypromise.js
According to the principle analysis of 1.2.3 above, we define three states and create oneMyPromise
Of the class, the actuator executes immediately, and the initialization state isPENDING
To defineresolve
.reject
Method with the following code:
const PENDING = "pending" / / wait for
const FULFILLED = "fulfilled" / / success
const REJECT = "reject" / / fail
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
// The initial state waits
status = PENDING
resolve = () = > {
// If the state is not waiting prevents the program from executing downward
if (this.status ! == PENDING)return
// Change the status to Successful
this.status = FULFILLED
}
reject = () = > {
// If the state is not waiting prevents the program from executing downward
if (this.status ! == PENDING)return
// Change the state to failed
this.status = REJECT
}
}
Copy the code
- According to the appeal 4. 5. Principle analysis, we need to define
then
Method, mainly to determine the current state of the call success or failure of the function, need to be declared in advancesuccessCallback
andfailCallback
Are the success and failure callback functions, respectively. The value of success needs to be passed in the callback functionvalue
Or send an error messagereason
, sovalue
andreason
To be declared in advance, the code is as follows:
// Declare the initial value returned on success
value = undefined
// Declare the reason for the return failure
reason = undefined
// Declare the successful callback function
successCallback = undefined
// Declare the failure callback function
failCallback = undefined
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECT) {
failCallback(this.reason)
}
}
Copy the code
Because we need to pass value and Reason values to the successCallback and failCallback callbacks in our then method, we should save the value and reason values in resolve and Reject, respectively. Change the code as follows:
resolve = value= > {
// If the state is not waiting prevents the program from executing downward
if (this.status ! == PENDING)return
// Change the status to Successful
this.status = FULFILLED
// Save the successful value and pass it to the then method
this.value = value
}
reject = reason= > {
// If the state is not waiting prevents the program from executing downward
if (this.status ! == PENDING)return
// Change the state to failed
this.status = REJECT
// Save the cause after the failure, and pass it to the then method
this.reason = reason
}
Copy the code
At this point, the base is complete and needs module.exports = MyPromise export
Iv. Final code and usage
MyPromise.js
const PENDING = "pending" / / wait for
const FULFILLED = "fulfilled" / / success
const REJECT = "reject" / / fail
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
// The initial state waits
status = PENDING
// Declare the initial value returned on success
value = undefined
// Declare the reason for the return failure
reason = undefined
// Declare the successful callback function
successCallback = undefined
// Declare the failure callback function
failCallback = undefined
resolve = value= > {
// If the state is not waiting prevents the program from executing downward
if (this.status ! == PENDING)return
// Change the status to Successful
this.status = FULFILLED
// Save the successful value and pass it to the then method
this.value = value
}
reject = reason= > {
// If the state is not waiting prevents the program from executing downward
if (this.status ! == PENDING)return
// Change the state to failed
this.status = REJECT
// Save the cause after the failure, and pass it to the then method
this.reason = reason
}
then (successCallback, failCallback) {
if (this.status === FULFILLED) {
successCallback(this.value)
} else if (this.status === REJECT) {
failCallback(this.reason)
}
}
}
module.exports = MyPromise
Copy the code
Create index.js to import our Pormise class and use it with the following code:
const MyPromise = require('./MyPromise') let promise = new MyPromise((resolve, Reject) => {resolve(' reject ') // reject(' failure message ')}) promise.then(value => {console.log(value) // success}, Reason => {console.log(reason) // failure information})Copy the code
Enter node index.js in the console to start