首页 > 解决方案 > JavaScript:等待递归树完成,其中每个递归级别都是 API 调用

问题描述

我正在尝试使用递归 API 调用构建 JSON 树,但我遇到了数据结构的流控制问题。如何在 BuildTree 函数堆栈结束之前阻止流程?

这是部分代码。提前致谢。

//FIRST CALL TO RETRIEVE THE ROOT
function callFW() {
    d3.json(url, function(data) { //?<----- api call
            Tree["uid"] = data.request.uid
            Tree["hid"] = data.firmware.meta_data.hid
            Tree["size"] = data.firmware.meta_data.size
            Tree["children"] = [];
            
            BuildTree(data.firmware.meta_data.included_files,Tree["children"])
            //WAIT FOR BUILDTREE
            console.log(Tree)
        } 
}

BuildTree 函数是这样的:

async function BuildTree(included_files, fatherNode){ 
        if( included_files.length > 0){
            promises = [];

            included_files.forEach(function(item) {
                url = endpoint+"file_object/"+item+"?summary=true";
                promises.push(axios.get(url));
            });

            Promise.all(promises).then(function (results) {
                results.forEach(function (response) {
                    
                    var node = {}
                    node["uid"]= response.data.request.uid
                    node["hid"]= response.data.file_object.meta_data.hid
                    node["size"] = response.data.file_object.meta_data.size
                    node["children"] = []

                    fatherNode.push(node)

                    BuildTree(response.data.file_object.meta_data.included_files, node["children"])
                    


                });
            });
        }
    }

标签: javascriptasynchronousrecursionasync-awaittree

解决方案


async无缘无故地使用关键字,因为您没有await在函数内部使用。你不妨使用它:)

async function BuildTree(included_files, fatherNode) {
    if (included_files.length > 0) {

        let promises = included_files.map( item => {
            let url = endpoint + "file_object/" + item + "?summary=true";
            return axios.get(url)
        });

        const results = await Promise.all(promises);

        for(let response of results){

            var node = {}
            node["uid"] = response.data.request.uid
            node["hid"] = response.data.file_object.meta_data.hid
            node["size"] = response.data.file_object.meta_data.size
            node["children"] = []

            fatherNode.push(node)

            await BuildTree(response.data.file_object.meta_data.included_files, node["children"]);
        };
    }
};

然后你可以简单地await BuildTree

function callFW() {
    d3.json(url, async function(data) {
            Tree["uid"] = data.request.uid
            Tree["hid"] = data.firmware.meta_data.hid
            Tree["size"] = data.firmware.meta_data.size
            Tree["children"] = [];
            
            await BuildTree(data.firmware.meta_data.included_files,Tree["children"]);

            console.log(Tree)
        })
}

推荐阅读