In JavaScript, how do you control loops in asynchronous callback functions?

  node.js, question
var SearchJavaStrate={
        findCil:function(cb){
            child_process.exec("java -XshowSettings:properties",function(error, stdout, stderr){
                var java_env=stderr.toString().match(/sun.boot.library.path.加/)[0];
                if(java_env){
                    java_env=path.join(java_env.match(/=.加/)[0].substr(1),"/javaw.exe")
                    console.log(15,java_env)
                    cb(false,java_env)
                }else{
                    cb(true)
                }
            })


        },
        find32Dir:function(cb){
            if(fs.existsSync("c:/Program Files/java/")){
                var java_env='c:/Program Files/java/'
                var java_dir=fs.readdirSync(java_env)[0]
                if(java_dir.length>0||java_dir){
                    var java_env=path.join(java_env,java_dir,"/bin/javaw.exe")
                    cb(false,java_env)
                }else{
                    cb(true)
                }
            }

        },
        find64Dir:function(cb){
            if(fs.existsSync("c:/Program Files (x86)/java/")){
                var java_env='c:/Program Files (x86)/java/'
                var java_dir=fs.readdirSync(java_env)[0]
                if(java_dir.length>0||java_dir){
                    var java_env=path.join(java_env,java_dir,"/bin/javaw.exe")
                    cb(false,java_env)
                }else{
                    cb(true)

                }
            }
        }
    }

    var SearchJavaContext=function(){
        var cache=[];
        var add=function(strate){
            strate.forEach(function(e,i){
                cache.push(function(cb){
                    SearchJavaStrate[e](cb)
                })
            })
        }




        return {
            init:function(strate,cb){
                if(strate&&strate.length>1){
                    add(strate)
                    console.log(cache)
                    var len=cache.length;
                    var i=0;
                    function funcFor(fn){
                        console.log(fn.toString())
                        fn(function(next,data){
                            if(next){
                                i加加;
                                if(i>len){
                                    cb(null)
                                }
                                arguments.callee(cache[i])
                            }else{
                                cb(data)
                            }
                        })
                    }
                    funcFor(cache[i])
                }
            }
        }
    }()



    SearchJavaContext.init(["findCil","find64Dir","find32Dir"],function(data){
        console.log("89",data)
        if(data){
            event.sender.send("searchJave:result",data)
        }

    })

Here is a piece of code in which all properties under SearchJavaStrate are functions, and then in SearchJavaContext’s init method, this pile of properties is added to an array array whose contents are roughly as followsfunction(cb){SearchJavaStrate[“findCil”},…..]
After being added to the array, you need to loop through these array functions.
Now there is a problem is
If the result has been returned when executing the first function, then there is no need to execute the second function and jump out of the loop directly.
However, the results returned by execution are asynchronous, so as the title says, how to control loops in asynchronous callback functions
The above I used recursive method to realize the control of the loop ..
I implore all great gods to give me guidance.

RecommendasyncSuch as library, there are related API
Just to solve your problem.

In addition, I have previously written a library specifically to solve such problems:
https://github.com/manxisuo/JFlow
It is written for fun and for reference only.