确定recursion函数何时完成

我有一个function,在一个大图上进行广度优先search。 目前该应用程序运行并在一段时间后完成。 我想添加一个finished事件给EventEmitter。

我的第一个想法是为每个Recursive过程实现一个计数器。 但是如果某个Recursive进程没有调用counter-- method,这可能会失败。

 var App = function(start, cb) { var Recursive = function(a, cb) { // **asynchronous** and recursive breadth-first search } var eventEmitter = new EventEmitter(); cb(eventEmitter); Recursive(start); }; 

如果所有的Recursive函数都完成了,怎样才能发出finished消息呢?

编辑应用程序不是search图中的东西,它必须遍历完整的graphics才能完成。 并不知道图中有多less元素。

Edit2像计算reflection一样是完美的,但似乎并不存在于JavaScript中。

该图非常不稳定,我正在做一些嵌套的asynchronous调用,都可能失败。 有没有办法知道什么时候所有的asynchronousrecursion调用完成而不使用计数器?

尝试这样的事情:

 var App = function(start, cb) { var pendingRecursive = 0; var eventEmitter = new EventEmitter(); cb(eventEmitter); var Recursive = function(a) { // breadth-first search recursion // before each recursive call: pendingRecursive++; Recursive(/*whatever*/); // at the end of the function if (--activeRecursive == 0){ eventEmitter.emit('end'); } } pendingRecursive = 1; Recursive(start); }; 

基本上,您只需在recursion调用之前增加一个计数器,然后在调用结束时递减计数,这样可以有效地计算未完成调用的数量,当调用为零时,您可以发出事件。

JavaScript是单线程的。

所以除非Recursive(start);setTimeoutajax那样有asynchronous调用,在调用recursion函数后触发完成的事件是安全的。

一般的asynchronousAPI传递一个done函数。

所以你会有

 Recursive(start, function() { // trigger finished. }); var Recursive = function(a, done) { ... }; 

done ,用户可以done调用。

你可以在函数之外使用一个布尔值作为标志,并在到达目标节点时改变它的值吗? 也许你的recursion情况可以在布尔值的情况下,当发现节点,你可以更新它的价值…或者你问你的recursion函数完成的基本情况是什么?

尝试这样的基于Adriens的答案

 /** * Function to search for a file recursively from a base directory * returns an array of absolute paths for files that match the search * criteria */ let recursiveFileSearch = ( baseDir, fileId ) => { let pathsArray = []; pendingRecursive = 1; //recursive funcion to get all config paths let getFilePaths = ( baseDir ) => { //require inbuilt path and filesystem modules let path = require ( 'path' ); let fs = require ( 'fs' ); //read the files in the base directory let files = fs.readdirSync ( baseDir ); //fetch all config files recursively for ( let i = 0 ; i < files.length; i ++ ) { let file = files [ i ]; let filePath = path.resolve ( baseDir, file ); //get file stats let fileStats = fs.lstatSync ( filePath ); let isFile = fileStats.isFile ( ); let isDir = fileStats.isDirectory ( ); if ( isFile && file === fileId ) { pathsArray.push ( filePath ); } if ( isDir ) { pendingRecursive++; getFilePaths( filePath ); } } //decrement the recursive flag if (--pendingRecursive == 0){ return pathsArray; } }; return getFilePaths ( baseDir ); }; //Testing the recursive search let baseDir = __dirname; let filePaths = recursiveFileSearch ( baseDir, "your file name" );