In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what are the relevant knowledge points of the javascript Async function?" in the operation of actual cases, many people will encounter such a dilemma, and then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Preface
In the asynchronous processing scheme, the most concise and elegant is the async function (hereinafter referred to as the A function). After the necessary block packaging, the A function can aggregate multiple related asynchronous operations like synchronous operations, making the relationship between them clearer, the process more concise, and the debugging more convenient. It is essentially the syntax sugar of the Generator function, which, in popular terms, is an enhanced version of asynchronous processing using the G function.
Try
Learning A function must have Promise foundation, * also understand Generator function, if necessary, you can see the extension section.
In order to intuitively feel the charm of the A function, we use the Promise and A functions to do the same asynchronous operation. The purpose of this async is to get the user's message list, which needs to be paged, which is controlled by the background. The specific action is: first get the total number of messages, and then correct the number of pages that need to be displayed (the total number may change each time you switch to a different page), * * pass parameters and obtain the corresponding data.
Let totalNum = 0; / / Total comments number. Let curPage = 1; / / Current page index. Let pageSize = 10; / / The number of comment displayed in one page. / / use the main code of the A function. Async function dealWithAsync () {totalNum = await getListCount (); console.log ('Get count', totalNum); if (pageSize * (curPage-1) > totalNum) {curPage = 1;} return getListData ();} / use the main code of Promise. Function dealWithPromise () {return new Promise ((resolve, reject) = > {getListCount () .then (res = > {totalNum = res; console.log ('Get count', res); if (pageSize * (curPage-1) > totalNum) {curPage = 1;} return getListData ()}) .then (resolve) .catch (reject);} / / starts executing the dealWithAsync function. / / dealWithAsync () .then (res = > {/ / console.log ('Get Data', res) / /}) .catch (err = > {/ / console.log (err); / /}); / / starts executing the dealWithPromise function. / / dealWithPromise () .then (res = > {/ / console.log ('Get Data', res) / /}) .catch (err = > {/ / console.log (err); / /}); function getListCount () {return createPromise (100) .catch (() = > {throw' Get list count error';}) } function getListData () {return createPromise ([], {curPage: curPage, pageSize: pageSize,}). Catch (() = > {throw 'Get list data error';});} function createPromise (data, / / Reback data params = null, / / Request params isSucceed = true, timeout = 1000,) {return new Promise ((resolve, reject) = > {setTimeout () = > {isSucceed? Resolve (data): reject (data);}, timeout);});}
Comparing the two simple functions of dealWithAsync and dealWithPromise, we can directly find that using the A function is no different from synchronization code except for the await keyword. Using Promise requires a lot of wrapped chain operations according to the rules, resulting in too many callback functions, which is not simple enough. In addition, each asynchronous operation is separated and the data passed on its success or failure is defined, which is close to the actual development.
1 enter the court
1.1 form
A function is also a function, so it has the properties that an ordinary function should have. However, there are two differences in form: one is that when defining an A function, the function keyword needs to be preceded by the async keyword (meaning asynchronous), indicating that it is an A function. Second, the await keyword (meaning wait) can be used inside the A function, which means that the result that follows will be treated as an asynchronous operation and wait for it to complete.
Here are several ways to define it.
/ / declarative async function A () {} / / expression let A = async function () {}; / / as object attribute let o = {A: async function () {}}; / / abbreviated let o as object attribute = {async A () {}}; / / arrow function let o = {A: async () = > {}}
1.2 return value
Executing the A function will return a Promise object on a fixed basis.
After getting the object, you can monitor the callback function in case of success or failure to listen. If the function executes smoothly and ends, the state of the returned P object changes from waiting to success, and the return result of the return command is output (undefined if not). If the function fails in the middle of execution, JS will assume that the A function has completed execution, and the state of the returned P object will change from waiting to failure, and the error message will be output.
/ / successful execution case A1 (). Then (res = > {console.log ('successful execution', res); / / 10}); async function A1 () {let n = 1 * 10; return n;} / failed execution case A2 (). Catch (err = > {console.log ('failed execution', err); / / i is not defined. }); async function A2 () {let n = 1 * i; return n;}
1.3 await
The await command can only be used inside A functions, not even ordinary functions that exist inside A functions.
The engine uniformly treats the following values after await as a Promise, and calls Promise.resolve () to convert values that are not Promise objects. Even if this value is an instance of Error, after conversion, the engine still treats it as a successful Promise, and its data is an instance of Error.
When the function executes to the await command, it pauses execution and waits for the subsequent Promise to finish. If the P object eventually succeeds, the successful return value is returned, which is equivalent to replacing await xxx with the return value. If the P object eventually fails and the error is not caught, the engine directly stops executing the A function and changes the status of the returned object to failure, outputting the error message.
*, the return x expression in the A function is equivalent to the abbreviation of return await x.
/ / successful execution case A1 (). Then (res = > {console.log ('successful execution', res); / / output 100 in about two seconds. }); async function A1 () {let N1 = await 10; let N2 = await new Promise (resolve = > {setTimeout (()) = > {resolve (10);}, 2000);}); return N1 * N2;} / / failed execution case A2 (). Catch (err = > {console.log ('execution failed', err); / / output 10 in about two seconds. }); async function A2 () {let N1 = await 10; let N2 = await new Promise ((resolve, reject) = > {setTimeout () = > {reject (10);}, 2000);}); return N1 * N2;} 2 enter the room
2.1 Secondary and concurrent
For await commands that exist in JS statements (for, while, etc.), the engine also pauses execution when it encounters. This means that you can directly use loop statements to handle multiple asynchronies.
Here are two examples of dealing with secondary events. The A function is particularly concise in dealing with successive asynchrony, which is no different from synchronous code as a whole.
/ / the behavior results of the two methods A1 and A2 are the same, outputting 10 times every other second, three times. Async function A1 () {let N1 = await createPromise (); console.log ('N1, N1); let N2 = await createPromise (); console.log ('N2, N2); let n3 = await createPromise (); console.log ('N3, n3);} async function A2 () {for (let I = 0; I)
< 3; i++) { let n = await createPromise(); console.log('N' + (i + 1), n); } } function createPromise() { return new Promise(resolve =>{setTimeout (() = > {resolve (10);}, 1000);});}
Next are three examples of dealing with concurrency. The A1 function uses Promise.all to generate an aggregate async, which is simple but less flexible, with only success and failure. The A3 function is relative to A2 only to show how to use the async function with the array traversal method. The emphasis is on the understanding of A2 function.
The A2 function uses circular statements, which are actually secondary to get each asynchronous value, but are quite concurrent in the overall time (you need to understand it here). Because each async has already been executed when the reqs array is created, and then although it is acquired one by one, the total time spent is independent of the traversal order and is always equal to the time spent by the most time-consuming asynchrony (regardless of traversal, execution, and other time consumption).
/ / the behavior results of the three methods A1, A2 and A3 are the same, and they all output [10, 10, 10] after about a second. Async function A1 () {let res = await Promise.all ([createPromise (), createPromise (), createPromise ()]); console.log ('Data', res);} async function A2 () {let res = []; let reqs = [createPromise (), createPromise (), createPromise ()]; for (let I = 0; I
< reqs.length; i++) { res[i] = await reqs[i]; } console.log('Data', res); } async function A3() { let res = []; let reqs = [9, 9, 9].map(async (item) =>{let n = await createPromise (item); return n + 1;}); for (let I = 0; I)
< reqs.length; i++) { res[i] = await reqs[i]; } console.log('Data', res); } function createPromise(n = 10) { return new Promise(resolve =>{setTimeout (() = > {resolve (n);}, 1000);});}
2.2 error handling
Once the Promise after await is converted to rejected, the entire async function is terminated. However, many times we do not want to terminate the entire function because of the failure of an asynchronous operation, so reasonable error handling is needed. Note that the errors mentioned here do not include errors that are parsed or executed by the engine, but simply Promise objects whose state changes to rejected.
There are two ways to deal with it: one is to wrap the Promise object first so that it always returns a successful Promise. The second is to use try.catch to catch errors.
Both / / A1 and A2 are executed, and the return value is 10. A1 (). Then (console.log); A2 (). Then (console.log); async function A1 () {let n; n = await createPromise (true); return n;} async function A2 () {let n; try {n = await createPromise (false);} catch (e) {n = e;} return n;} function createPromise (needCatch) {let p = new Promise ((resolve, reject) = > {reject (10);}); return needCatch? P.catch (err = > err): P;}
2.3 implementation principle
As mentioned in the preface, the A function is an enhanced version of asynchronous processing using the G function. In that case, let's start with its improvement and take a look at its implementation principle based on G function. The improvement of A function over G function is reflected in these aspects: better semantics, built-in executor and return value is Promise.
Better semantics. The G function identifies this as the G function by using * after the function, while the A function adds the async keyword before the function. In the G function, you can use the yield command to pause execution and hand over execution authority, while the A function uses await to wait for the result to be returned asynchronously. Obviously, async and await are more semantic.
/ / G function function* request () {let n = yield createPromise ();} / A function async function request () {let n = await createPromise ();} function createPromise () {return new Promise (resolve = > {setTimeout () = > {resolve (10);}, 1000);});}
Built-in actuator. Calling the A function automatically performs and waits for the asynchronous operation step by step until the end. If you need to use the G function to perform asynchronous operations automatically, you need to create a self-executor for it. Through the self-actuator to automate the execution of the G function, its behavior is basically the same as the A function. It can be said that the improvement of the A function compared with the G function is the built-in self-executor.
/ / both print out 10 every other second, repeat twice. / / A function A (); async function A () {let N1 = await createPromise (); console.log (N1); let N2 = await createPromise (); console.log (N2);} / / G function, executed using a self-actuator. Spawn (G); function* G () {let N1 = yield createPromise (); console.log (N1); let N2 = yield createPromise (); console.log (N2);} function spawn (genF) {return new Promise (function (resolve, reject) {const gen = genF (); function step (nextF) {let next; try {next = nextF ();} catch (e) {return reject (e)) } if (next.done) {return resolve (next.value);} Promise.resolve (next.value) .then (function (v) {step (function () {return gen.next (v);});}, function (e) {step (function () {return gen.throw (e);});} step (function () {return gen.next (undefined);});}) } function createPromise () {return new Promise (resolve = > {setTimeout (()) = > {resolve (10);}, 1000);});}
2.4 execution order
Before understanding the execution order between the inside of the A function and the outside of the A function, you need to understand two points: one is that the instance method of Promise is deferred to the end of this round of events. For more information, please see the link. The second is that the Generator function changes the execution power by calling the instance method to control the execution order of the program. For more information, please see the link. A good understanding of the execution order of A function can grasp the existence of these three more clearly.
Take a look at the following code to compare the results of the A1, A2, and A3 methods.
F (A1); / / print out successively: 1 3 4 2 5. F (A2); / / print out successively: 1 3 2 4 5. F (A3); / / print out: 1 / 3 / 2, print out: 4 / 9 after two seconds. Function F (A) {console.log (1); A (). Then (console.log); console.log (2);} async function A1 () {console.log (3); console.log (4); return 5;} async function A2 () {console.log (3); let n = await 5; console.log (4); return n;} async function A3 () {console.log (3); let n = await createPromise () Console.log (4); return n;} function createPromise () {return new Promise (resolve = > {setTimeout () = > {resolve (9);}, 2000);});}
Some surface forms can be summarized from the results. Executing the A function immediately executes its function body until the await command is encountered. When an await command is encountered, the execution power shifts to the outside of the A function, that is, the execution of the external code starts regardless of the internal execution of the A function. After the execution of the external code (this round of events), continue to execute the code following the previous await command.
Summed up to half of the success, and then began to analyze its causes. If you know something about this building, you will not forget the aunt 'self-actuator', will you? I guess I forgot. The essence of A function is G function with self-actuator, so to explore the execution principle of A function is to explore the execution principle of G function using self-actuator. Remember?
Looking at the following code, the G function with the same logic will get the same result as the A function.
F (A); / / print out: 1 / 3 / 2, print out: 4 / 9 after two seconds. F (() = > {return spawn (G);}); / / print out: 1.32 first, print out: 4.9 after two seconds. Function F (A) {console.log (1); A (). Then (console.log); console.log (2);} async function A () {console.log (3); let n = await createPromise (); console.log (4); return n;} function* G () {console.log (3); let n = yield createPromise (); console.log (4); return n } function createPromise () {return new Promise (resolve = > {setTimeout () = > {resolve (9);}, 2000);} function spawn (genF) {return new Promise (function (resolve, reject) {const gen = genF (); function step (nextF) {let next; try {next = nextF ();} catch (e) {return reject (e);} if (next.done) {return resolve (next.value)) } Promise.resolve (next.value) .then (function (v) {step (function () {return gen.next (v);});}, function (e) {step (function () {return gen.throw (e);} step (function () {return gen.next (undefined);}
When the G function is executed automatically, the following expression is wrapped with Promise.resolve when the yield command is encountered, and a callback function is set for it. Whether the Promise has a result immediately or after a certain period of time, its callback function is deferred until the end of the current round of events. And then the next step, and then the next step. The same applies to the A function, when it comes to the await command (omitting three or five words here), so there is such an order of execution.
This is the end of the content of "what are the relevant knowledge points of javascript Async function". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.