Javascript Node.js-使用async.瀑布和将JSON响应与下划线.extend合并的依赖API请求调用

Javascript Node.js-使用async.瀑布和将JSON响应与下划线.extend合并的依赖API请求调用,javascript,json,node.js,underscore.js,Javascript,Json,Node.js,Underscore.js,好吧,这里发生了很多事情,但我尽量把问题孤立起来 在node.js Express项目中,我进行了两个API请求调用,第二个调用依赖于第一个调用。为了简化这个任务,我使用了异步模块中的瀑布方法 在getVideoDetails函数中,我将第二个API请求与从第一个响应中检索的videoId放在循环中,以获取视频数据 目前我的问题是,var extended只给我body值,而我希望它是result+body 我想知道这是因为\u extend不应该在循环中。 我也不清楚如何使结果可以被循环外的c

好吧,这里发生了很多事情,但我尽量把问题孤立起来

在node.js Express项目中,我进行了两个API请求调用,第二个调用依赖于第一个调用。为了简化这个任务,我使用了异步模块中的瀑布方法

getVideoDetails
函数中,我将第二个API请求与从第一个响应中检索的
videoId
放在循环中,以获取视频数据

目前我的问题是,
var extended
只给我
body
值,而我希望它是
result+body

我想知道这是因为
\u extend
不应该在循环中。 我也不清楚如何使结果可以被循环外的callback(result)访问

async.waterfall([

    function getVideos (getVideoCallback) {

        ...

    },

    function getVideoDetails (result, getVideoDetailsCallback) {

        var urls = [];

        Object.keys(result.items).forEach(function(item) {
            urls.push ("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=" + result.items[item].contentDetails.videoId + "&key=xxx");
        })

        urls.forEach(function(url) {
            request( url, function(err, response, body) {
                if(err) { console.log(err); return; }
                body = JSON.parse(body);    

                var extended = _.extend(result, body);

                getVideoDetailsCallback(null, extended);

            });
        });

    }
], function (err, result) {

    if (err) { console.log(err); return; }

    callback(result);

});

如果你想按顺序做这些事情

1。异步生成数组

2。对数组中的每个项目执行一些异步处理

3。在处理数组后执行异步操作

…这是一种使用异步库的方法

var request = require("request");
var _ = require("lodash");
var db = require("whatever you are using");

module.exports = function(req, res) {
    var params = req.params;

    async.waterfall([

        function getVideos(next) {
            db.findAll().then(function(rows) {
                next(null, rows);
            });
        },

        function forEachVideoDoSomethingAsync(videos, next) {
            var urls = videos.map(function(obj) {
                obj.url = obj.name + "http://googleapi.com/whatever";
                return obj;
            });

            /** this is the part you are missing **/

            //async.map takes three arguments
            //1. the array you want to work on
            //2. a function that is applied to each item in the array
            //    the iterator function receives two arguments
            //    1. the current item in the array
            //    2. a callback you invoke when you want to move to the next item
            //3. a callback that is executed once the loop has been completed

            async.map(urls, function(currentItem, callback) {
                request(currentItem.url, function(err, response, body) {
                    if (err) 
                        return console.log(error);
                    //you probably have to extend the current item in the array with the response object
                    var json = JSON.parse(body);
                    var extended = _.extend(currentItem, json);
                    //each item you send via the callback will be pushed into the result of async.map
                    callback(extended);
                });
            }, function(err, urls_extended) {
                //urls_extended is now an array of extended items
                //now you have to exit the waterfall
                next(null, urls_extended);
            });

        }

    ], function(err, urls_extended) {
        if (err) 
            return console.log(err);
        //exit the entire process
        res.send(urls_extended);
    })

};

请求
方法来自哪里?您不能在
forEach
循环中放入异步操作,您必须嵌套
async。每个
都在瀑布中的一个函数中。我使用的是请求模块。如果我不能将异步操作放在循环函数中,我如何使用从第一个请求中动态获得的多个属性发出第二个API请求?@Daniel_L我正试图遵循你的建议,但仍然不确定它要去哪里。请看一看谢谢你的全面回答。在getVideos中,我不仅获取视频URL,在这个响应中,我还获取第二个API请求无法获取的视频片段数据。所以在最后一个瀑布函数中,我需要合并来自第一个和第二个请求的响应。你能补充一下怎么做吗?