Node.js - 使用async.waterfall的依赖API请求调用,并使用underscore.extend合并JSON响应 [英] Node.js - dependant API request calls using async.waterfall and merge JSON response with underscore.extend

查看:153
本文介绍了Node.js - 使用async.waterfall的依赖API请求调用,并使用underscore.extend合并JSON响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,这里有很多事情发生,但我试图尽可能地隔离这个问题。

Okay, there is quite a bit happening here but I tried to isolate the issue as much as possible.

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

In my node.js Express project, I'm making two API request calls that the second call is dependant on the first. To make this task easier, I'm using waterfall method from async module.

getVideoDetails 函数中,我把第二个API请求循环使用 videoId 从第一个获取视频数据的响应中重新获得。

In getVideoDetails function, I put the second API request in loop with the videoId retreived from the first response to get video data.

目前的问题我有, var extended 只给我 body 值,而我希望它是结果+正文

The problem currently I have is that, var extended only gives me body value while I expect it to be result + body.

我不知道是因为 _extend 不应该在环。
我也不清楚如何在循环外调用回调(结果)来访问结果。

I wonder that's because _extend shouldn't be inside the loop. I'm also not clear how I can make the result accessible to call callback(result) outside the loop.

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);

});


推荐答案

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

If you want to do these things in order...

1。异步生成数组

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

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

...然后这是使用异步库执行此操作的一种方法。

...then this is one way you could do it with the async library.

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);
    })

};

这篇关于Node.js - 使用async.waterfall的依赖API请求调用,并使用underscore.extend合并JSON响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆