Node.js - 使用async.waterfall的依赖API请求调用,并使用underscore.extend合并JSON响应 [英] Node.js - dependant API request calls using async.waterfall and merge JSON response with underscore.extend
问题描述
好的,这里有很多事情发生,但我试图尽可能地隔离这个问题。
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屋!