How to use request within async.each in node.js Ex

2019-09-10 20:05发布

In my node.js project, I need to make iterative API request so I'm using async.each method.

The console complains that url is not defined and I understand this because I've only declared urls which is an array of url.

I'm just not sure how I can put together request() from request module inside async.each. To satisfy async.each() I've placed urls as the first argument but request() itself requires a query string argument which is url.

I'm also using _.extend from Underscore to merge two responses but I'm not sure where I have it currently is in the right place.

Can someone please point me in the right direction?

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

})

async.each(
  urls,
  request(url, function(err, response, body) {
    if (err) {
      console.log(err);
      return;
    }
    body = JSON.parse(body);
  }),
  function() {
    var extended = _.extend(result, body);
    getVideoDetailsCallback(null, extended)
  });

2条回答
Evening l夕情丶
2楼-- · 2019-09-10 20:06

If you want to get the results from each iteration. I suggest using async.map. Map returns an array of results to the final callback.

Here's an example,

var async = require('async');

async.map([ 1, 2, 3, 4 ], function ( num, cb ) {
  cb(null, num);
}, function (error, results) {
  console.log(results);
});
// output: [ 1, 2, 3, 4 ] 

As for your code snippet, your second argument is the wrong type. You're invoking request which doesn't return a function. The second argument is expected to be a function so what you need to do is wrap the request around function definition.

async.map(urls, function(url, callback) {
  request(options, callback);
}, function (error, results) {
  // do something with results
});
查看更多
Melony?
3楼-- · 2019-09-10 20:09

It seems you're calling request with callbacks and all, and not just referencing it, which means you probably need an anonymous function call.

Also, if you want an array at the end, or whatever you're extending, you could just use async.map instead, and do something like

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

async.map(urls, function(url, callback) {
    request(url, function(err, response, body) {
        if (err) {
            return callback(err);
        }
        callback(null, JSON.parse(body));
    });
}, function(err, extended) {
    if (err) {
        // handle error
    }
    // extended is an array containing the parsed JSON
    getVideoDetailsCallback(null, extended); 
});
查看更多
登录 后发表回答