Promise is a solution to asynchronous programming that is more logical and powerful than traditional solutions-callback functions and events. It was first proposed and realized by the community, ES6 it into the language standard, unified the usage, the native provided the Promise object.
If you think this is a sad love story, sorry, then you are "by the title."
Some time ago, in the process of developing a visual process tool with Nodejs, it involves the functions of batch processing, such as batch n-style files.
We know that Nodejs reads files into blocking and non-blocking 2 kinds
The blocking processing process is as follows
Assuming that each file is processed in T[0,1,2...N], all files are processed at time = t[0] + ... + t[n], which is the sum of all the tasks that are time-consuming.
non-blocking processing flow is as follows
Assuming that each file has processing time of T[0,1,2...N], all files are processed at time = Maxim (t[0],..., t[n]), which is the longest time in all tasks.
node for the fast processing of IO, reducing the duration of the entire task, I am ready to use "non-blocking mode" to read the file and processing.
To prevent the demo code from being coupled to business logic, use the delay function to simulate the asynchronous method, as follows
"Use strict";
Let callbacks = [
function () {
settimeout () => {
console.log (' 3000 ');
},3000);
},
function () {
settimeout () => {
console.log (' 1000 ');
},1000);
},
function () {
SetTimeout (() => {
console.log (' 4000 ');
},4000);
}
];
for (Let i = 0; i < callbacks.length; i++) {
callbacks[i] ();
}
If you simply display the contents of a file and have nothing to do with each other, the above pattern has basically satisfied the requirements, but assuming that we need to give the user feedback after all the file processing is complete, the various callbacks that are completely without any logical relationship will not meet our requirements.
So I added a counter, the counter initial value is the total number of tasks, whenever a task is completed, the counter minus 1, when the counter is 0 o'clock, all tasks are completed, the modified code as follows
"Use strict";
Let callbacks = [
function () {
settimeout () => {
console.log (' 3000 ');
Changecount ();
},3000);
},
function () {
settimeout (() => {
console.log (' 1000 ')
; Changecount ();
},1000);
},
function () {
settimeout (() => {
console.log (' 4000 ')
; Changecount ();
},4000);
}
],
count = 3;
function Changecount () {
count--;
if (count <= 0) {
console.log (' All task completed ');
}
for (Let i = 0; i < callbacks.length; i++) {
callbacks[i] ();
}
It looks like our goal is basically achieved, and one day, we're going to deal with Sprite merge pull, for a single style file, when we extract the files to be merged after the picture is merged, at the same time, according to the return of the picture in the sprite map of the location and size of the incoming style files need to make rules changes, Then the merged sprite and style changes become a "blocking" operation, and the modification of the style depends on the result of the picture merging. Do not be afraid, we have a universal callback, the simulation of the sample code is as follows.
"Use strict";
function Task () {
readFile ();
}
function ReadFile () {
settimeout () => {
console.log (' Read file ');
Sprite ();
},1000);
function Sprite () {
settimeout () => {
console.log (' sprite images ');
},2000)
}
task ();
The form is in fact the front end of the students often said callback set callback, if more than the serial task, these callbacks will be nested in the code reading, problem positioning and other aspects brought some trouble. Commonly known as "Callback Hell", but I personally think that a small number of serial processing This is also a good way.
To solve this problem, some good people in the industry have developed some libraries to handle asynchronous tasks, such as async, which I used in the project, and its task API is very clear and easy to use. But today it is not the protagonist, interested in the children's shoes can go to search for their own study, today we want to introduce you to the ES6 promise, back to our title "Whose Promise", OK, is ES6.
Nanyi Teacher has a translation of the ES6 tutorial, said more detailed, address, the basis of knowledge I do not repeat, this article focuses on how to use the promise to solve the above-mentioned problems involved in the asynchronous control and serial processing.
Take a look at scenario 1 above, monitor a bunch of asynchronous tasks, and then start the post-processing when all the tasks are complete.
Promise provides a Promise.all API for wrapping multiple promise into a new promise, and all tasks are completed and the Promise method is executed, as shown in the following code
How to deal with scene 2. Scenario 2 is a typical waterfall Flow task model, and although all tasks are asynchronous, these asynchronous operations need to be serialized, and the tasks in all task lists are advanced first out of queue and executed sequentially. The main use of the resolve feature of promise is that when a promise (P1) Its resolve is another promise object (P2), the timing of the P1 is dependent on the result of the P2, and when P2 is normal resolve, P1 begins execution. The code is as follows:
This article does not explain the basic users of promise, you can learn from the article in Ruan Teacher, here is the use of promise to build common 2 kinds of task mode (parallel mode, serial mode) for a simple simulation of the implementation, concrete with the scene combination I believe it will still shine.
In the process of using promise, it is important to realize that the whole promise can be understood as a state machine, in Execution (Pending), completion (resolve), failure (reject), which is not necessarily true, but also emphasizes that you have a very clear understanding of the tasks to be performed. , when the state is reversed, what array is passed into the task flow pipeline, how to handle the exception, and so on.
Finally a summary, who used to know. Have fun.