循环内有多个API调用

时间:2018-02-13 07:54:20

标签: javascript node.js

循环内的多个API调用 我在循环中进行多个API调用,函数在promise内部调用并将数据传递给body,这部分工作正常,在函数中返回一个对API进行多次调用的promise,然后继续进行我必须得到所有的结果。但当我控制台记录结果时,它显示空数组。

    var rp = require('request-promise');
    var watchonlinemovie = []; 


 exports.db = function(body){

    return new Promise((resolve,reject)=>{




        if(body.lenght > 0)
        { 
            body.forEach(movie)
            { 
                let title = movie.title;
                title = (title.slice(0,title.indexOf('('))).trim();
                let year = movie.title; 
                year = year.slice(year.indexOf('(')+1,year.indexOf(')'));

                let call = "http://www.omdbapi.com/?t="+title+"&y="+year+"&apikey="+key2+"&plot=full";

         rp(call)
          .then((body) => {


                   let movie = JSON.parse(body);

                   watchonlinemovie.push({
                     title: movie.Title, 
                     year:movie.Year, 
                     rating:movie.Rated,
                     duration:movie.Runtime,
                     genre:movie.Genre,
                     director:movie.Director, 
                     actors:movie.Actors,
                     image:movie.Poster,
                     href:movie.link, 
                   });     
         })
         .catch(err => { 
           reject(err);
         });
            }
        }

        resolve(watchonlinemovie);
    });
}

2 个答案:

答案 0 :(得分:0)

您可以使用async.eachOfLimit继续所有行。您可以将限制调整为1比1或5比5,或全部并行(如果您有数千行,请不要这样做。)

10乘10的例子。

    var async = require("async");
    var rp = require('request-promise');


     exports.db = function(body){

        return new Promise((resolve,reject)=>{

            var watchonlinemovie = []; 

            // change the limit here
            // process all request with a batch of 10
            async.eachOfLimit(body, 10, function(movie, i, ecb){

                // function called for each line in body

                let title = movie.title;
                title = (title.slice(0,title.indexOf('('))).trim();
                let year = movie.title; 
                year = year.slice(year.indexOf('(')+1,year.indexOf(')'));

                let call = "http://www.omdbapi.com/?t="+title+"&y="+year+"&apikey="+key2+"&plot=full";

                rp(call)
                .then((body) => {


                   let movie = JSON.parse(body);

                   watchonlinemovie.push({
                     title: movie.Title, 
                     year:movie.Year, 
                     rating:movie.Rated,
                     duration:movie.Runtime,
                     genre:movie.Genre,
                     director:movie.Director, 
                     actors:movie.Actors,
                     image:movie.Poster,
                     href:movie.link, 
                   });

                   // proceed next movie
                   return ecb(null); 
                })
                .catch(err => { 

                    // stop the async process
                    return ecb(err);
                 });
             })

            }, function(err){

                // final callback, when all request in the body has been proceed
                if(err)
                {
                     reject(err);
                }
                else
                {
                    resolve(watchonlinemovie); 
                }
            });

        });
    }

答案 1 :(得分:0)

这是一个使用promises的解决方案,我添加了一些不允许承诺拒绝的内容,而是创建了Fail类型值,您可以从结果中选择它们。

如果您需要限制,可以从here导入文件。

var rp = require('request-promise');

const movieToUrl = key2 => movie => {
  const title = movie.title.slice(0, title.indexOf('(')).trim();
  const year = movie.title.slice(title.indexOf('(') + 1, title.indexOf(')'));
  let call = "http://www.omdbapi.com/?t=" + title + "&y=" + year + 
    "&apikey=" + key2 + "&plot=full";
};

const movieDataToMovieInstance = movie => ({
  title: movie.Title,
  year: movie.Year,
  rating: movie.Rated,
  duration: movie.Runtime,
  genre: movie.Genre,
  director: movie.Director,
  actors: movie.Actors,
  image: movie.Poster,
  href: movie.link,
});

const Fail = function(reason){this.reason=reason;};
const isFail = x=>(x&&x.constructor)===Fail;
const isNotFail = x=>!isFail(x);

//if you want to throttle promises like max5 active or max5 per second
//  you can use throttle library here:
//  https://github.com/amsterdamharu/lib/blob/master/src/index.js
//const max5=lib.throttle(5);//this is max 5 active connections
//const max5=throttlePeriod(5,1000);//this is max 5 per second


exports.db = function (body) {
  return Promise.all(
    body.map(
      movieToUrl(key2)//key2 comes out of nowhere
      //throttled version
      //.then(max5(rp))
      .then(rp)
      .then(movieDataToMovieInstance)
      .catch(err=>new Fail([body,err]))
    )
  );
};

//example how to use:
exports.db(someBody)
.then(
  results=>{
    const successes = results.filter(isNotFail);
    const failures = results.filter(isFail);
  }
)