Nodejs 中的控制流--the Do Style(二)

时间:2022-04-19 00:58:54
最近看到一篇关于node中改变异步编程控制流的文章:Control Flow in Node Part II.

翻译如下:(有删减)

当前在Node中,有两种方式可以处理异步返回值问题:“回调”和“事件发射”。这些你都可以在Nodejs官网上了解到。我在这里将谈论另一种管理异步返回[值或流]事件的方式。

回调和事件发射器之间的区别是什么?

回调其实就是一个function,但是用于处理异步的。

Nodejs 中的控制流--the Do Style(二)

fs.readFile()传入一个文件名称作为参数,然后“返回”文件的内容。但它最终并不是真正地返回了文件内容,而是把结果传递给了作为参数的回调函数。

有时你想要监听的事件可能会触发很多次。例如,在一个web服务器中,当处理一个请求时,可能"data"事件会被触发一次或者多次,最后“end”事件才会被触发。

Nodejs 中的控制流--the Do Style(二)

它与回调的不同在于:你要么得到一个结果,要么得到一个错误。对于事件来讲,你永远都不能得到两者,或者超过一种结果(注:这里侧重于表达“事件的触发”,例如要么你就触发一个success事件,要么就触发一个error事件)。所以,如果有超过两个事件,它们可能会被调用很多次,那么你就需要更为强大、灵活的事件发射器。

Node.js 的回调风格

Node最初使用promises代替callback,在经过很多争辩、讨论之后,node决定用简单的callback来取代promise。
在node中,任何异步的函数都接受一个回调来作为它最后一个参数。在fs模块中的大部分函数都是这样。并且,这些回调函数大部分都会以一个error参数(如果有的话),作为其第一个参数。

Nodejs 中的控制流--the Do Style(二)

这里有另一种方式

Promises 工作地很好,但在读了inimino的持续使用后,我备受鼓舞地尝试了一种新的方式。
还记得我们的第一个示例吗?假设fs.readFile被以像下面这种形式来使用:

Nodejs 中的控制流--the Do Style(二)

取代寄期望于一个回调,它返回了一个函数,该函数“期望”两个回调方法:一个用于读取成功之后的处理,另一个用于处理失败。我称之为 Do Style,等一会儿你将会看到为何要这么写。

如果产生该回调风格

我们将编写自定义的函数,让它不是直接返回一个值。用这种新的风格,让我们编写一个看起来类似的函数:fileWrite(假设fs模块里的函数也转换成了这种风格):

Nodejs 中的控制流--the Do Style(二)

注意看,将错误信息链接给我们的调用端是多么容易!同时这段使用的代码也更加简短并且易于阅读。创建这种风格的关键在于:不是产生一个promise并返回,而是返回一个函数,它携带两个回调函数作为参数,然后在需要的时候,直接调用它们。

Do 类库

我今天给出一个很短的类库作为其早期的版本。或者说,它就是一个能够进行并发响应的独立函数。

实现

Nodejs 中的控制流--the Do Style(二)

但在这里合并了所有回调的响应,这在某种程度上能够发挥更为强大的威力以及编写更有趣的代码。

单独处理

让我们假设有个readFile的函数使用了这个技术。下面是它如何使用的:

Nodejs 中的控制流--the Do Style(二)

 并行处理

现在,让我们使用Do类库合并那些操作:

Nodejs 中的控制流--the Do Style(二)

它并行完成两个异步操作,当两个操作都完成之后触发回调。注意,在没有产生错误的时候,它只触发成功的那个回调函数,如果有一个错误,它将被传递给一个公共的错误处理器(回调)中去。

 当然,你也可以传递一个“预操作的数组”:

Nodejs 中的控制流--the Do Style(二)

 

//============================写在最后=============================
 最后还有一种方式,可读性不敢恭维,如果有想了解的童鞋,请自行异步到原作者博客。这种方式是提供了一种回调的变相风格,简单地使用是可以增强代码的可读性的,不建议过度使用。认为它影响可读性的人,大可不必介意。