仅使用Node.js进行异步HTTP(S)遍历

尼科

我尝试遍历一堆HAL / JSON资源,这些资源为通过hrefs连接并通过https检索的项目树建模。也就是说,“项目”可以是请假或其他分支与其他叶子。las,我做对了。遍历将始终结束,即在完成完整递归之前,在我的代码示例的最后一条语句中命中then()回调。实际上,我只将第一层放回了孩子中。

我的问题:我错过了什么才能做到正确?

我仍在学习Node.js,但是我已经在较早的示例中成功使用了Promise。我在这里问这个问题,因为我只能使用模块https和集成的Nodejs东西。其他示例经常使用其他模块和/或不能解决我遇到的问题。

var traverse = function(rootItemUrl, depth, children) {
    var deferred = Promise.defer();

    var itemUrl = rootItemUrl;
    var options = {
        'path'      : itemUrl
        , 'host'      : "<host>"
        , 'method'  : 'GET'
        , 'headers' : {
            'Content-Type'  : 'application/json'
            , 'Accept'      : 'application/json'
            , 'Forwarded'   : 'proto=https;host=<host>'
            , 'Cookie'      : options_.headers['Cookie']
        }
    };

    https.get(options, onItemResultResponse);
    function onItemResultResponse(itemResultResponse) {
        var body = [];
        itemResultResponse.on('data', function onDataChunk(data) {
            body.push(data);
        });
        itemResultResponse.on('end', onItemResultData);
        itemResultResponse.on('error', onRequestItemsError);
        function onRequestItemsError(e) {
            console.log('Get items failed for <'+rootItemUrl+'>.');
            deferred.reject();
        }
        function onItemResultData() {
            var items = [];
            var itemResult = JSON.parse(Buffer.concat(body).toString());
            var embedded = itemResult._embedded;
            var collection = embedded ? embedded['collection'] : undefined;
            if(collection) {
                var itemsObject = collection._links['item'];
                if(itemsObject) {
                    if(itemsObject.length) {
                        for(var i = 0; i < itemsObject.length; ++i) {
                            items.push(itemsObject[i].href);
                        }
                    } else {
                        items.push(itemsObject.href);
                    }
                }
            }

            var type = itemResult.base.type;
            var name = itemResult.common.name;

            var text = repeatChar(depth, '\t') + ('folder' === type ? '- (folder) ' : '')+ 'depth: '+depth+' '+name;
            children.push(text);
            //console.log(text);

            if(items.length) {
                for (var j = 0; j < items.length; ++j) {
                    traverse(items[j], depth + 1, children)
                        .then(function() {deferred.resolve(depth);});
                }
            } else {
                deferred.resolve(depth);
            }
        }
    }

    return deferred.promise;
};

var children = [];
traverse(rootItemUrl, 0, children)
                        .then(function toConsole(depth) {
                            // >> Alas I hit this point too early <<
                            console.log(children);
                            console.log('End');
                        });
尼科

对于对此答案感兴趣的人,请继续阅读,因为我找到了一个没有承诺的解决方案我完全摆脱了对回调的承诺。请注意,与原始代码相比,我进行了一些更改,例如,收集结果而不是将它们打印到递归代码中的stdout中,并且删除了其他一些绒毛。

var traverse = function(options, rootItemUrl, depth, done) {
    var results = [];

    options.path = rootItemUrl;
    https.get(options, onItemResultResponse);
    function onItemResultResponse(itemResultResponse) {
        var body = [];
        itemResultResponse.on('data', function onDataChunk(data) {
            body.push(data);
        });
        itemResultResponse.on('end', onItemResultData);
        itemResultResponse.on('error', onRequestItemsError);
        function onRequestItemsError(e) {
            console.log('Get items failed for <' + rootItemUrl + '>.');
            done(e);
        }
        function onItemResultData() {
            var items = [];
            var itemResult = JSON.parse(Buffer.concat(body).toString());

            var embedded = itemResult._embedded;
            results.push(toItemInfo(itemResult, depth));
            var collection = embedded ? embedded['collection'] : undefined;
            var embeddedItems = collection ? collection._embedded : undefined;
            if (embeddedItems) {
                var itemsObject = embeddedItems['item'];
                if (itemsObject) {
                    if (itemsObject.length) {
                        for (var i = 0; i < itemsObject.length; ++i) {
                            items.push(itemsObject[i]);
                        }
                    } else {
                        items.push(itemsObject);
                    }
                }

                var itemInfos = new Array(items.length);
                for (var iii = 0; iii < items.length; ++iii) {
                    itemInfos[iii] = toItemInfo(items[iii], depth + 1);
                }

                var ii = 0;
                (function next() {
                    var nextItemInfo = itemInfos[ii++];
                    if (!nextItemInfo) {
                        return done(null, results);
                    }
                    if ('folder' === nextItemInfo.type) {
                        traverse(options, nextItemInfo, depth + 1, function done(err, result) {
                            results = results.concat(result);
                            next();
                        });
                    } else {
                        results.push(nextItemInfo);
                        next();
                    }
                })();
            }
        }
    }
};
traverse(options, rootItemUrl, 0, function done(e, results) {
   var text = '';
   for(var ii = 0; ii < results.length; ++ii) {
        var itemInfo = results[ii];
        text += repeatChar(itemInfo.depth, '\t') + ('folder' === itemInfo.type ? '- (folder) ' : '') + 'depth: ' + itemInfo.depth + ' ' + itemInfo.name;            
    }
    console.log(text);
    console.log("End");
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在node.js中使用异步瀑布

来自分类Dev

Node.js承诺,异步或仅回调

来自分类Dev

使用累加器遍历Node.js异步目录

来自分类Dev

在不使用异步库帮助器类的情况下在node.js中异步进行for循环

来自分类Dev

使用Highland.js进行异步地图

来自分类Dev

使用循环在Node.js中进行异步作业调度

来自分类Dev

将异步与http.get,Node JS一起使用

来自分类Dev

使用邮件传输的Node.js Winston日志记录仅发送uncaughtException作为电子邮件

来自分类Dev

使用异步Node.JS来服务HTTP请求

来自分类Dev

使用For循环遍历异步功能(数据库查询,Node.js)

来自分类Dev

使用Node.js异步请求在Redis中进行循环

来自分类Dev

在node.js中使用异步模块

来自分类Dev

仅使用Node JS中包含数据的变量的正确方法是什么?

来自分类Dev

使用Node.js进行异步编程-遍历一系列链接,打开它们并将它们保存到JSON中

来自分类Dev

使用Vega和Node.js的画布出现问题(仅服务器端)

来自分类Dev

如何在Node.js中使用异步瀑布进行API调用

来自分类Dev

我可以使用.dotenv库作为HTML脚本,而仅导入npm或node.js吗?

来自分类Dev

node.js无法使用http进行剩余调用

来自分类Dev

Node.js仅使用数组中的最后一项

来自分类Dev

使用累加器遍历Node.js异步目录

来自分类Dev

是否有任何仅使用核心模块实现restapi和auth的node.js教程?

来自分类Dev

使用Node.js异步请求在Redis中进行循环

来自分类Dev

在Node.js中使用异步瀑布进行函数迭代

来自分类Dev

Node.js将URL字符串转换为仅使用路径名

来自分类Dev

mongoDB-光标仅使用node.js驱动程序更新1个文档

来自分类Dev

仅使用 PFX 的 Node JS https 服务器

来自分类Dev

使用cheerio js进行节点遍历

来自分类Dev

使用 saga js 进行异步操作

来自分类Dev

在 node.js 8.10 中使用异步瀑布进行 AWS Lambda 查询

Related 相关文章

  1. 1

    在node.js中使用异步瀑布

  2. 2

    Node.js承诺,异步或仅回调

  3. 3

    使用累加器遍历Node.js异步目录

  4. 4

    在不使用异步库帮助器类的情况下在node.js中异步进行for循环

  5. 5

    使用Highland.js进行异步地图

  6. 6

    使用循环在Node.js中进行异步作业调度

  7. 7

    将异步与http.get,Node JS一起使用

  8. 8

    使用邮件传输的Node.js Winston日志记录仅发送uncaughtException作为电子邮件

  9. 9

    使用异步Node.JS来服务HTTP请求

  10. 10

    使用For循环遍历异步功能(数据库查询,Node.js)

  11. 11

    使用Node.js异步请求在Redis中进行循环

  12. 12

    在node.js中使用异步模块

  13. 13

    仅使用Node JS中包含数据的变量的正确方法是什么?

  14. 14

    使用Node.js进行异步编程-遍历一系列链接,打开它们并将它们保存到JSON中

  15. 15

    使用Vega和Node.js的画布出现问题(仅服务器端)

  16. 16

    如何在Node.js中使用异步瀑布进行API调用

  17. 17

    我可以使用.dotenv库作为HTML脚本,而仅导入npm或node.js吗?

  18. 18

    node.js无法使用http进行剩余调用

  19. 19

    Node.js仅使用数组中的最后一项

  20. 20

    使用累加器遍历Node.js异步目录

  21. 21

    是否有任何仅使用核心模块实现restapi和auth的node.js教程?

  22. 22

    使用Node.js异步请求在Redis中进行循环

  23. 23

    在Node.js中使用异步瀑布进行函数迭代

  24. 24

    Node.js将URL字符串转换为仅使用路径名

  25. 25

    mongoDB-光标仅使用node.js驱动程序更新1个文档

  26. 26

    仅使用 PFX 的 Node JS https 服务器

  27. 27

    使用cheerio js进行节点遍历

  28. 28

    使用 saga js 进行异步操作

  29. 29

    在 node.js 8.10 中使用异步瀑布进行 AWS Lambda 查询

热门标签

归档