Control Flow in Node

本文探讨了Node.js中异步编程的挑战,通过实例讲解如何利用回调函数和自定义库实现任务的串行与并行执行,提高开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近读了关于Control Flow in Node的几篇文章,写的非常好,贴在这里与大家分享一下,希望对你写node有帮助。

 

One of the unique aspects of programming in an async framework like node is the ability to decide between which function will run in serial and which will run in parallel. While there are no built-in methods for managing this in node, I'll discuss some of the tricks I came up with while writing the node-blog engine that generates this site.

Parallel vs Serial

Usually in an application you have steps that can't run until the result from a previous step is known. In normal sequential programming this is easy because every statement waits till the previous one finishes.

This is the case in Node too, except for functions that would otherwise perform blocking IO. This includes things like scanning a directory, opening a file, reading from a file, querying a database, etc...

For my blog engine I have a tree structure of files that need to be processed. Here are the steps I need to accomplish:

  • Get a list of articles.
  • Read in and parse the articles.
  • Get a list of authors.
  • Read in and parse the authors.
  • Get a list of HAML templates.
  • Read in all the HAML templates.
  • Get a list of static resource files.
  • Read in the static files.
  • Write article html pages.
  • Write author pages.
  • Write index page.
  • Write feed page.
  • Write static resources.

As you can see, there are several items that can be run independent of each other. For example I can do all of the file reading at once without any problems, but I can't read any file until I've scanned the directory to know what files to read. I can write all the files at the same time once their contents are calculated, but I won't know what to put in them until all the reads are done.

A counter for grouped parallel actions

For the simple case of scanning a directory and reading all the files into one object, we can employ a simple counter.

 

Nesting callbacks is a great way to ensure they run synchronously. So inside the callback of readdir, we set a countdown to the number of files to read. Then we start a readFile for each of the files. These will run in parallel and finish in any arbitrary order. The important thing is that we're decrementing the counter after each one finishes. When the counter goes back to 0 we know that was the last file to read.

Passing callbacks to avoid excessive nesting

Now, if we wanted to execute more code now that we have the contents of the files, we would put it inside the inner-most nesting where the comment is. This can become a problem real quick when a program has 7 levels of sequential actions.

So let's modify the example to pass callbacks:

 

Now we have made a composite asynchronous function. It takes some arguments (the path in this case), and calls a callback when everything inside is done. All the logic inside it, and importantly the several levels of nesting are now compressed into a single unnested callback.

Combo library

I made a simple Combo library the other day. It basically wraps up the task of counting events and calling a callback when the last one finishes. Also it preserves the original order of callbacks registered irrespective of their actual response time.

 

Suppose you wanted to read some data from a database and read some more data from a file, and then do something else once the two were completed.

 

The database query and the file read will happen at the same time. When they are both done, then the callback given to theCombo constructor will get called. The first argument will be the database result and the second will be the file contents.

Conclusion

The techniques taught here are:

  • Nest callbacks to get serial behavior.
  • Collocate method calls to get parallel behavior.
  • Use callbacks to untangle nested serial actions.
  • Use counters to know when groups of parallel actions are finished.
  • Use libraries like Combo to ease the pain.

For a larger example of these patterns see the build.js file in the node-blog engine.

 

更多文章参考:

 

  • Tim Caswell:

Control Flow in Node Part I

 

Control Flow in Node Part II

 

Control Flow in Node Part III

 

The Step of the Conductor

 

  • kriszyp:

https://github.com/kriszyp/node-promise

 

  • willconant: 

https://github.com/willconant/flow-js

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值