简体   繁体   English

在node.js中的循环内进行api调用

[英]Making an api call inside a loop in node.js

I am trying to scan the top 100 movie torrents on the pirate bay using node and add a movie poster for each result. 我正在尝试使用node扫描海盗湾上排名前100的电影洪流,并为每个结果添加电影海报。

I am using these libraries 我正在使用这些库

thepiratebay imdb-api thepiratebay imdb-api

I am able to find top 100 and return the results with no problems 我能够找到前100名并毫无问题地返回结果

app.get('/movies', function(req, res){
 tpb.topTorrents(207).then(function(topMovies){
    async.map(topMovies, tpb.getTorrent, function(err, results){
        res.send(results);
    })
 })
});

I am also able to look up movies via an IMDB ID and return the results 我还可以通过IMDB ID查找电影并返回结果

app.get('/imdb', function(req, res){
 imdb.getReq({ id: 'tt2660888' }, function(err, things) {
    res.send(things);
 });
});

What I am trying to do is loop over the top 100 results pull the imdb id out of the description field out and query imdb replacing the picture field with result. 我想做的是循环遍历前100个结果,将imdb id从描述字段中拉出,并查询imdb将图片字段替换为结果。

app.get('/movies', function(req, res){
 tpb.topTorrents(207).then(function(topMovies){
     async.map(topMovies, tpb.getTorrent, function(err, results){
         for (var value of results) {
             if (S(value.description).contains('www.imdb.com/title/')) {
                 var imdbId = S(value.description).between('www.imdb.com/title/', '/').s
                     imdb.getReq({ id: imdbId }, function(err, movie) {
                         value["picture"] = movie.poster
                     });
             }
         }
         res.send(results);
     })
 })
});

This isn't working for some reason but it makes sense to me intuitively. 由于某些原因,这没有用,但从直觉上来说对我来说是有意义的。 If I remove the imdb-api call and replace it with value["picture"] = "foo". 如果我删除了imdb-api调用,并将其替换为value [“ picture”] =“ foo”。 It does work. 确实有效。 I'm not sure if this is related to how node handles loops. 我不确定这是否与节点处理循环的方式有关。 I'm new to the JS world and have a ruby background 我是JS世界的新手,具有红宝石背景

Thanks in advance 提前致谢

You are on the right track with the async module but the imdb requests are also asynchronous so res.send just gets called with the initial result of async.map 您使用async模块走上了正确的轨道,但是imdb请求也是异步的,因此res.send只会被async.map的初始结果async.map

You can use another async.map for the imdb calls and them chain them with async.waterfall which will pass the results of the first function as an argument to the second ( async.apply just invokes the tpb function with your topMovies ). 您可以使用另一个async.map的IMDB电话和他们连锁他们async.waterfall将通过第一函数的结果作为参数传递给第二( async.apply只是调用与您的TPB功能topMovies )。

function tpb (topMovies, done) {
    async.map(topMovies, tpb.getTorrent, done);
}

function imdb (movies, done) {
    function lookup (value, callback) {
        if (S(value.description).contains('www.imdb.com/title/')) {
            var imdbId = S(value.description).between('www.imdb.com/title/', '/').s
            imdb.getReq({ id: imdbId }, function(err, movie) {
                value["picture"] = movie.poster
                return cb(err, value);
            });
        } else {
            return callback(null);
        }
    }

    async.map(movies, lookup, done);
}

app.get('/movies', function(req, res){
    tpb.topTorrents(207).then(function(topMovies){
        async.waterfall([async.apply(tpb, topMovies), imdb], function (err, results) {
            if (err) {
                // do error handling
            }
            return res.send(results);
        });
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM