Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to probe into Asynchronous callback processing in koa

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article is about how to deeply explore the asynchronous callback processing in koa. The editor finds it very practical, so I share it with you. I hope you can get something after reading this article. Let's take a look at it with the editor.

1. Callback pyramid and ideal solution

We all know that javascript is a single-threaded asynchronous non-blocking language. Of course, asynchronous non-blocking is one of its advantages, but a large number of asynchronous operations inevitably involve a large number of callback functions, especially when asynchronous nesting, there will be the problem of callback pyramid, so that the readability of the code is very poor. For example, the following example:

Var fs = require ('fs'); fs.readFile ('. / file1', function (err, data) {console.log (data.toString ()); fs.readFile ('. / file2', function (err, data) {console.log (data.toString ());})})

In this example, the contents of two files are read and printed successively, in which the reading of file2 must be done after the end of file1 reading, so the operation must be performed in the callback function read by file1. This is a typical callback nesting, and there are only two layers, in actual programming, we may encounter more layers of nesting, such code writing is undoubtedly not elegant.

In our imagination, a more elegant way of writing should be something that looks synchronous but asynchronous, like this:

Var data; data = readFile ('. / file1'); / / the following code is the callback part console.log (data.toString ()) after the execution of * readFile; / / the following code is the callback data = readFile ('. / file2') of the second readFile; console.log (data.toString ())

In this way, the callback of hell is completely avoided. In fact, koa allows us to write asynchronous callback functions in this way:

Var koa = require ('koa'); var app = koa (); var request=require (' some module'); app.use (function* () {var data = yield request ('http://www.baidu.com'); / / below is the asynchronous callback part this.body = data.toString ();}) app.listen (3000)

So what makes koa so magical?

2. Generator cooperates with promise to realize asynchronous callback synchronous writing.

The key point, as mentioned in the previous article, is that generator has a similar "break point" effect. When a yield is encountered, it pauses, gives control to the functions that follow the yield, and resumes execution the next time it returns.

In the koa example above, not all objects can be followed by yield. Must be of a specific type. In the co function, you can support promise, thunk functions, and so on.

In today's article, we'll take promise as an example to see how to use generator and promise to achieve asynchronous synchronization.

Still use * to read file examples to analyze. First, we need to modify the function of reading the file to encapsulate it into a promise object:

Var fs = require ('fs'); var readFile = function (fileName) {return new Promise (function (resolve, reject) {fs.readFile (fileName, function (err, data) {if (err) {reject (err);} else {resolve (data);}})})} / the following is a sample var tmp = readFile ('. / file1') used by readFile. Tmp.then (function (data) {console.log (data.toString ();})

About the use of promise, if you are not familiar with it, you can take a look at the syntax in es6. (in the near future, I will also write an article to teach you how to use es5 syntax to implement a promise object with basic functions. Please look forward to you ^ _ ^)

To put it simply, promise can write callback functions in the form of promise.then (callback). But our goal is to cooperate with generator to really achieve silky and smooth synchronization. How to cooperate? take a look at this code:

Var fs = require ('fs'); var readFile = function (fileName) {return new Promise (function (resolve, reject) {fs.readFile (fileName, function (err, data) {if (err) {reject (err);} else {resolve (data) }})})} / / put the process of reading the file in generator var gen = function* () {var data = yield readFile ('. / file1'); console.log (data.toString ()); data = yield readFile ('. / file2'); console.log (data.toString ());} / / manually execute generator var g = gen (); var another = g.next () / / another.value is the returned promise object another.value.then (function (data) {/ / call g.next again to execute generator from the breakpoint and return data as an argument to var another2 = g.next (data); another2.value.then (function (data) {g.next (data);})})

In the above code, we yield readFile in generator, and the callback statement code is written in the code after yield, which is written synchronously, realizing the assumption at the beginning of the article.

After yield, what we get is that an another.value is a promise object, and we can use the then statement to define a callback function. The content of the function is to return the read data to generator and continue to let generator execute from the breakpoint.

Basically, this is the core principle of asynchronous callback synchronization. In fact, if you are familiar with python, you will know that there is a concept of "co-program" in python, which is basically implemented using generator (I think it is suspected that es6's generator borrows from python~).

However, the above code is still executed manually. So like the previous article, we also need to implement a run function to manage the process of generator so that it can run automatically!

3. Let the synchronized callback function run automatically: the writing of a run function

A closer look at the part of the previous code that manually executes generator also reveals a rule that allows us to write a recursive function instead:

Var run=function (gen) {var g; if (typeof gen.next==='function') {gallegen;} else {g=gen ();} function next (data) {var tmp=g.next (data); if (tmp.done) {return;} else {tmp.value.then (next);}} next ();}

The function takes a generator and makes the async in it execute automatically. Using this run function, let's automate the last asynchronous code:

Var fs = require ('fs'); var run = function (gen) {var g; if (typeof gen.next =' function') {g = gen;} else {g = gen ();} function next (data) {var tmp = g.next (data); if (tmp.done) {return;} else {tmp.value.then (next);}} next () } var readFile = function (fileName) {return new Promise (function (resolve, reject) {fs.readFile (fileName, function (err, data) {if (err) {reject (err);} else {resolve (data);}})} / / put the process of reading the file in generator var gen = function* () {var data = yield readFile ('. / file1') Console.log (data.toString ()); data = yield readFile ('. / file2'); console.log (data.toString ());} / / the following only need to put gen into run to automatically execute run (gen)

By executing the above code, you can see that the terminal prints out the contents of file1 and file2 in turn.

It should be pointed out that the run function here only supports promise for simplicity, while the actual co function also supports thunk and so on.

In this way, the two major functions of the co function are basically fully introduced, one is the flow control of the onion model, and the other is the automatic execution of asynchronous synchronization code.

The above is how to deeply explore the asynchronous callback processing in koa. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report