在Nodejs中管理大量的回调递归

Mac*_*iek 18 javascript recursion v8 callback node.js

在Nodejs中,几乎没有阻塞I/O操作.这意味着几乎所有nodejs IO代码都涉及许多回调.这适用于对数据库,文件,进程等进行读写操作.典型示例如下:

var useFile = function(filename,callback){
    posix.stat(filename).addCallback(function (stats) {
        posix.open(filename, process.O_RDONLY, 0666).addCallback(function (fd) {
            posix.read(fd, stats.size, 0).addCallback(function(contents){
                callback(contents);
            });
        });
    });
};

...

useFile("test.data",function(data){
    // use data..
});
Run Code Online (Sandbox Code Playgroud)

我期待编写代码来进行许多 IO操作,所以我希望编写很多回调函数.我对使用回调很满意,但我担心所有的递归.我是否有可能遇到过多的递归并在某个地方吹过堆栈?如果我通过数千次回调对我的键值存储进行数千次单独写入,我的程序最终会崩溃吗?

我误解或低估了影响吗?如果没有,有没有办法解决这个问题,同时仍然使用Nodejs的回调编码风格?

Nic*_*itz 24

您显示的代码都不是使用递归.当你调用useFile它时posix.stat(),它会返回,并useFile在它运行完成时终止.稍后,当在底层系统内posix.stat()完成调用并且结果可用时,您为此添加的回调函数将被执行.该调用,然后在运行完成时终止.一旦该文件已被成功打开,回调函数即会执行,调用,然后将终止,因为它也已完成运行.最后,当读取结果可用时,将执行最里面的功能.posix.open()posix.read()

重要的一点是每个函数都运行完成,因为对posix.*()函数的调用是非阻塞的:也就是说,它们立即返回,导致在底层系统中启动了一些魔法.因此,每个函数都会终止,稍后事件将导致下一个函数执行; 但是没有任何递归.

代码的嵌套结构可以给人一种印象,即内部的东西必须在外面的东西到达它自己的终点之前完成.但是在这种异步事件驱动编程风格中,使用更深层次的方式看待嵌套更为有意义=>发生在后面.

编辑:尝试在每个嵌套函数结束之前立即添加一些日志语句; 这将有助于说明它们完成的顺序是从外部开始.