Node Asynchronous programming
I learned that node async programming can be divided into:
1. Callback function
2.pub/sub mode (publish/Subscribe mode)
3.promise
4.generator
5.async await
I. Direct callback function
This method is the most directly used asynchronous operation, such as SetInterval and Ajax, and so on, there are disadvantages:
1. Code difficult to read and prone to pyramid nesting problems;
2. Usually only one callback function can be used, which has a certain limit;
Fs.readfile ('/etc/passwd ', function (err, data) { if (err) throw err; Console.log (data);});
The function reads the/ETC/PASSWD, executes the callback function, and the error that is thrown between the two is passed into the callback function as a parameter.
Two. Publish/Subscribe Mode
This method is no longer limited to one-to-one, in many-to-many forms of monitoring events, can be very convenient to subscribe to and unsubscribe from the shortcomings are: the need for the use of Class library (JQuery), the order of events and callback functions is important.
Three. Promise
One of the drawbacks of a callback function is that it is prone to multiple layers of nested, hard-to-maintain scenes. The promise in Es6 Grammar solves this kind of problem. Promise contains three states: Pending, fulfilled, rejected, three states can only have two conversions (from Pending->fulfilled, pending->rejected), Also the conversion of the state can occur only once.
After the promise instance is generated, you can use the then method to specify the callback function for the resolved state and the Reject state, respectively:
The then method can accept two callback functions as arguments. The first callback function is called when the state of the Promise object becomes resolved, and the second callback function is called when the state of the Promise object changes to reject.
A) Then method returns promise. This enables serial operations of multiple asynchronous operations.
b) The conversion between several different asynchronous libraries has been implemented.
var p1 = new Promise (function (resolve, reject) { setTimeout (() = Reject (new Error (' Fail '))}) var p2 = new P Romise (function (resolve, reject) { setTimeout (() = Resolve (p1), +)}) p2.then (result = Console.log ( Result)) P2.catch (Error = Console.log (error))//Error:fail
The Promise.all method is used to wrap multiple Promise instances into a new Promise instance. Is the way we are using it in our project. If var p = Promise.all([p1,p2,p3]);
the state of P is determined by P1, P2, p3, it is divided into two cases.
(1) Only the state of P1, P2, P3 becomes fulfilled, and the return value of P1, P2, and P3 constitutes an array, which is passed to P's callback function.
(2) As long as P1, p2, P3 has a rejected,p state becomes rejected, at this time the first reject instance of the return value, will be passed to P's callback function.
Four. Generator
The biggest feature of generator is the ability to pause and restart functions, which is very useful for solving asynchronous operations there are two nouns that need to be aware of yield and next.
- Generator's resolution mechanism is a bit like a thread. The next method functions as a phased execution of the generator function. Each time the next method is called, an object is returned that represents the information for the current stage (the Value property and the Done property). The Value property is the expression following the yield statement, which represents the value of the current stage; The Done property is a Boolean value that indicates whether the generator function is finished, that is, whether there is a next stage.
- The yield command is a flag that flags an asynchronous operation, and if this command is removed, the function pauses as if it were executing a synchronous function, waits for execution to return, and then resumes execution from where it was paused.
The Generator function also provides a mechanism for data exchange and error handling. It can also deploy error handling code inside its functions, capturing errors thrown outside the body of the function.
function* Gen (x) { try { var y = yield x + 2; } catch (e) { console.log (e); } return y;} var g = Gen (1); G.next (); G.throw (' wrong ');//Error
In addition, the generator function has two small helper thunk functions (a mechanism for automating the process of generator functions, receiving and returning the execution of a program) and Co modules (for automatic execution of generator functions). )
Five. Async await
ES7 provides the async function, which becomes the syntactic sugar of the generator function, which is mostly replaced by async instead of *, with await instead of yield, and in addition, he brings some conveniences:
The invocation of the 1.generator function requires the use of the next method or the Co module, and the call of async and the normal function does not require any function;
2.co module conventions, the yield command can be followed only by the thunk function or the Promise object, and the Async function is followed by an await command that is a promise object and a value of the original type
Note that the await command can only be used in the Async function, and if used in a normal function, it will be an error.
Async function Dbfuc (db) {let docs = [{}, {}, {}]; Error Docs.foreach (function (doc) { await db.post (DOC); });
The above code will error because await is used in the normal function. However, if you change the parameters of the ForEach method to an async function, there is a problem.
Async function Dbfuc (db) {let docs = [{}, {}, {}]; May get error result Docs.foreach (async function (doc) { await db.post (DOC); });
The above code may not work properly, because at this point the three db.post operations will be executed concurrently, that is, execution at the same time, not secondary execution. The correct notation is to use a for loop.
Async function Dbfuc (db) {let docs = [{}, {}, {}]; For (Let doc of docs) { await db.post (DOC); }}
If you do want multiple requests to execute concurrently, you can use the Promise.all method.
Async function Dbfuc (db) {let docs = [{}, {}, {}]; Let promises = Docs.map ((doc) = Db.post (doc)); Let results = await promise.all (promises); Console.log (results);} or use the following notation for async function dbfuc (db) {let docs = [{}, {}, {}]; Let promises = Docs.map ((doc) = Db.post (doc)); Let results = []; For (let promise of Promises) { Results.push (await promise); } Console.log (results);}
The content is not very deep, the follow-up will continue to supplement and revise, I hope you can correct me
Node Asynchronous programming