1. An overview of the
Javascript is a single-threaded language (single-threaded/multi-threaded, blocking/non-blocking, synchronous, asynchronous). Refer to this article. All tasks are executed sequentially, but asynchronously for time-consuming operations (when the previous task ends, instead of executing the next task, the callback function is executed, The latter task is executed without waiting for the former task to finish.) See this article, four methods of asynchronous programming in JS: Callbacks, event listeners, publish/subscribe, and Promise objects. Here we discuss the use of Promises. Promises were added in ES6 to make asynchronous programming easier by eliminating the need for nested callbacks
2. Promise is introduced
2.1 Promise constructor
The Promise constructor takes a function as an argument that takes resolve and reject, which are also functions
const promise = new Promise(function(resolve, reject) {
// Code for asynchronous operations
if(success) {
return resolve(data); // data indicates the data returned by the asynchronous operation successfully
} else {
return reject(error); //data is the data returned on failure}})Copy the code
2.2 resolve and reject
Promise objects are like containers (or state machines) that contain asynchronous operations that have two outcomes: success or failure. This is a pity. When the asynchronous operation is successful, the pending state will be changed to a pity. At the same time, the resolve function will be triggered, which is used to transfer the result after the operation is successful. When an asynchronous operation fails, the pending status is changed to REJECT and the REJECT function is fired, which is used to pass out any errors reported after the operation fails
const promise = new Promise(function(resolve, reject) {
// Code for asynchronous operations
if(success) {
return resolve(data); // data indicates the data returned by the asynchronous operation successfully
} else {
return reject(error); //data is the data returned on failure}})Copy the code
Let’s look at the following code:
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1'})})}, 1000)function fn2() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn2')
},2000)
})
}
fn1().then(fn2)
Copy the code
The output is: fn1 fn2 does not execute, at which point we need to call resolve to execute the then() callback fn2
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1')
resolve('fn1'})})}, 1000)Copy the code
The output is: fn1 fn2 What happens if we call reject in fn1?
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1')
// resolve('fn1')
reject('wrong'+'fn1')
},1000)
})
}
fn1().then(fn2).then((data) => {
console.log(data)
})
Copy the code
The output is:
fn1().then(fn2).then((data) => {
console.log(data)
}, (err) => {
console.log(err)
})
Copy the code
The output is:
2.3 Then () method
When the Promise instance is generated, the then method is followed by the first callback to process the resolve and second callback to process the reject, as shown in the following code
promise
.then(function(data){
// Get the returned data and do some processing
console.log(data)
}, function(error) {
// Return failure to do some processing
console.log(error)
})
Copy the code
Return value of 2.3.1 then()
The then() method is a method of a Promise instance defined on a promise.prototype object. The then() method returns a new Promise instance (not the original Promise, So we can use the chain
var p1 = new Promise( (resolve, reject) = > {
setTimeout((a)= > resolve('p1'), 10);
});
p1.then( ret= > {
console.log(ret);
return 'then1';
}).then( ret= > {
console.log(ret);
return 'then2';
}).then( ret= > {
console.log(ret);
});
Copy the code
We start with the second then() method, whose resolve argument is the return value of the resolve statement of the previous THEN (). Chained THEN specifies a sequence of callbacks to be called. In this case, the previous callback may still return a Promise object (with asynchronous operations), and the latter callback will wait for the state of the Promise object to change before it is invoked
getJSON("/post/1.json").then(function(post) {
returngetJSON(post.commentURL); }).then(function funcA(comments) {
console.log("resolved: ", comments); },function funcB(err){
console.log("rejected: ", err); })Copy the code
In the code above, the callback specified by the first then method returns another Promise object. At this point, the callback specified by the second THEN method waits for the new Promise object state to change. Call funcA if it becomes Resolved and funcB if the state changes to Rejected. The above code can be written more succinctly if the arrow function is used
getJSON("/post/1.json").then(
post= > getJSON(post.commentURL)).then(
comments= > console.log("resolved: ", comments),
err => console.log("rejected: ", err));
Copy the code
Promise is chained as follows:
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1')
resolve('fn1'})})}, 1000)function fn2() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn2')
resolve('fn2'})})}, 2000)function fn3() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn3')
resolve('fn3'})})}, 3000)function fn4() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn4')
resolve('fn4')
},4000)
})
}
fn1().then(fn2).then(fn3).then((data) => {
console.log(data)
}, (err) => {
console.log(err)
})
Copy the code
The output is fn1>fn2>fn3 and we can also change the order of execution
function fn1() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn1')
reject(false})})}, 1000)function fn2() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn2')
resolve('fn2'})})}, 2000)function fn3() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn3')
resolve('fn3'})})}, 3000)function fn4() {
return new Promise(function(resolve, reject){
setTimeout(() => {
console.log('fn4')
resolve('fn4')
},4000)
})
}
fn1().then(fn2).then(fn3).then((data) => {
console.log(data)
}, (err) => {
if(err == false){
fn3().then(fn4)
}
})
Copy the code
The output is fN1 > FN3 > FN4
2.4 Catch () method
We tend to use a catch () method instead of writing a second callback in then(), which is similar to. Then (null, Rejection).
promise
.then(functionConsole. log(data)}). Catch (function(error) {// Do something when returning failure console.log(error)}Copy the code
Why use the catch () method? Let’s look at an example:
const promise = new Promise((resolve,reject) => {
console.log(1)
resolve('success')
})
promise
.then((data) => {
console.log(data)
console.log(a)
}, (err) => {
console.log(err)
})
Copy the code
ReferenceError: A is not defined The Error object of the Promise object has the bubbling property and will be passed back until it is caught. That is, an error is always caught by the next catch statement
var p = new Promise( (resolve, reject) => {
setTimeout(() => resolve('p1'), 10);
});
p.then( ret => {
console.log(ret);
throw new Error('then1');
return 'then1';
}).then( ret => {
console.log(ret);
throw new Error('then2');
return 'then2'; }). Catch (err => {// Can catch the previous error. console.log(err.toString()); });Copy the code
The output is p1 Error: then1
2.4.1 Return value of catch ()
Since catch() is an alias for.then(null, Rejection), then catch() returns a Promise object, so you can also call the then method afterwards
var p = new Promise((resolve, reject) = > {
resolve(x + 2);
});
p.then( (a)= > {
console.log('nothing');
}).catch( err= > {
console.log(err.toString());
return 'catch';
}).then( ret= > {
console.log(ret);
});
Copy the code
The output is: ReferenceError: x is not defined catch When an error occurs, the catch will first process the previous error and then pass the value to the later then method through the return statement. If no error is reported, the catch will be skipped, as shown in the following example:
var p = new Promise((resolve, reject) => {
resolve('p');
});
p.then( ret => {
console.log(ret);
return 'then1';
}).catch( err => {
console.log(err.toString());
return 'catch';
}).then( ret => {
console.log(ret);
});
Copy the code
3. I promise
3.1 Implement Ajax operations with Promise
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if(this.readyState ! = = 4) {return;
}
if (this.status === 200) {
resolve(this.response);
} else{ reject(new Error(this.statusText)); }}; const client = new XMLHttpRequest(); client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept"."application/json");
client.send();
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('Wrong', error);
});
Copy the code
3.2 Promise combined with ajax methods
var http = {
get: function(url) {
var promise = new Promise(function(resolve, reject) {
$.ajax({
url: url,
method: 'get',
success: function(data) {
resolve(data);
},
error: function(xhr, statusText) { reject(statusText); }}); });returnpromise; }}; http.get('data.php').then(function(data) {
document.write(data);
}, function(err) {
document.write(err);
});
Copy the code
3.3 Use promise to realize the example of asynchronous loading pictures
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
const image = new Image();
image.onload = function() {
resolve(image);
};
image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};
image.src = url;
});
}
var loadImage1 = loadImageAsync(url);
loadImage1.then(function success() {
console.log("success");
}, function fail() {
console.log("fail");
});
Copy the code
3.4 Promise is combined with axios method
function fetch(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response.data);
}, error => {
reject(error);
})
.catch(error => {
reject(error)
})
})
}
function lineStatus(params) {
return fetch('/ProductionLine/GetStatus', params)
}
function statisticsData(params) {
return fetch('/ProductionLine/GetWeightStatistics'. params) } lineStatus(this.lineId) .then((result) => { this.deviceStatus.run = result.TotleMoveMotor this.deviceStatus.stop = result.TotleStopMotor this.deviceStatus.lost = result.TotleLoseMotor this.deviceStatus.alarm = result.TotleAlarmMotor this.ProductionStatus = result.ProductionStatus console.log(result) }) .catch((error) => { console.log('Watt's gone... (; '⌒ `)')
})
statisticsData(this.lineId)
.then((result) => {
this.outputData.totalOutput = result.MainConveyorModel.OutPut
this.outputData.instantWeight = result.MainConveyorModel.InstantWeight
this.outputData.runningTime = result.MainConveyorModel.RunningTime
this.outputData.motorLoad = result.MainConveyorModel.MotorLoad
// console.log(result)
})
.catch((error) => {
console.log('Watt's gone... (; '⌒ `)')})Copy the code
The above is a common use of Promise in development. Thanks to the author for referring to the following articles
- Promise object [Ruan Yifeng]
- [es6 series] Learn the Promise
- Ruan Yifeng ES6– Promise object
- Resolve, reject, and catch in a Promise