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

时间:2016-10-23 18:29:25

标签: javascript node.js api loops

我正在尝试使用节点扫描海盗湾上的前100个电影种子,并为每个结果添加电影海报。

我正在使用这些库

thepiratebay imdb-api

我能够找到前100名并且没有任何问题返回结果

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

我也可以通过IMDB ID查找电影并返回结果

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

我想要做的是循环前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);
     })
 })
});

由于某些原因,这不起作用,但直觉上对我有意义。如果我删除imdb-api调用并将其替换为值[" picture"] =" foo"。它确实有效。我不确定这是否与节点处理循环有关。我是JS世界的新手,拥有红宝石背景

提前致谢

1 个答案:

答案 0 :(得分:0)

您使用异步模块走在正确的轨道上,但imdb请求也是异步的,因此res.send只会调用初始结果async.map

您可以使用另一个async.map进行imdb调用,然后将它们与async.waterfall链接起来,这会将第一个函数的结果作为参数传递给第二个函数(async.apply只调用你topMovies的tpb功能。

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