如何使用Nodejs进行多个API调用以将所有结果保存在一个json文件中?

时间:2017-07-26 09:36:29

标签: javascript json node.js api

我想一次性从JSON API获取不同网址(值)的结果,并将结果保存在一个json文件中。我的方法如下,但我在生成的对象和json文件中遇到挂起的Promises。有什么方法可以使用Promises解决这个问题,还是我应该使用回调?非常感谢任何提示。我相信可以编码得更好。

const fetch = require('node-fetch');
const util = require('util');

function getIndicator (indicator) {
  url = 'http://api.worldbank.org/countries/de/indicators/' + indicator + '/?date=2012:2018&format=json';
  let result = fetch(url)
    .then(function(res) {
      return res.json();
    })
    .then(function(json) {
      return json;
    })
  return result;
}

function loadIndicators () {
  let indicators = ['SP.POP.TOTL','SP.DYN.IMRT.IN','SP.DYN.LE00.IN'];
  let german_indicators = {};
  indicators.forEach(function (e) {
    german_indicators[e] = getIndicator(e);
  })
  return german_indicators;
}

let result = loadIndicators();
fs.writeFileSync('./data.json', util.inspect(result), 'utf-8');

3 个答案:

答案 0 :(得分:1)

您的getIndicatorloadIndicators函数可能会返回Promise,因此您可以Promise.all循环loadIndicators。{/ p>

const fetch = require('node-fetch');
const util = require('util');
function getIndicator(indicator) {
    const url = 'http://api.worldbank.org/countries/de/indicators/' + indicator + '/?date=2012:2018&format=json';
    return fetch(url)
        .then(function (res) {
            return res.json();
        });
}
function loadIndicators() {
    return new Promise((resolve, reject) => {
        const promises = [];
        let indicators = [
            'SP.POP.TOTL',
            'SP.DYN.IMRT.IN',
            'SP.DYN.LE00.IN'
        ];
        let german_indicators = {};
        indicators.forEach(function (e) {
            promises.push(new Promise((resolve, reject) => {
                getIndicator(e).then((result) => {
                    german_indicators[e] = result;
                    resolve();
                }).catch(reject);
            }));
        });
        Promise.all(promises).then(() => {
            resolve(german_indicators);
        }).catch(reject);
    });
}
loadIndicators().then((result) => {
    fs.writeFileSync('./data.json', util.inspect(result), 'utf-8');
}).catch(console.error);

答案 1 :(得分:1)

您可以等待所有承诺得到解决,每个解决方案都会将JSON添加到全局变量或文件中。使用promise库可能会非常棘手。

我建议使用bluebird或任何其他替代方案。特别针对您的问题,请查看bluebird的promise.all API。

答案 2 :(得分:0)

  

它认为这将更简单一个

var request = require('request');
var util = require('util');
var Q = require('q');
var fs = require('fs');

function loadIndicators() {
        var deferred = Q.defer();

        let indicators = [
            'SP.POP.TOTL',
            'SP.DYN.IMRT.IN',
            'SP.DYN.LE00.IN'
        ];
        let german_indicators = {};
        var promises = indicators.map((e)=>{
          var url = 'http://api.worldbank.org/countries/de/indicators/' + e + '/?date=2012:2018&format=json';

         request.get(url,function(err,res,body){

                 if(err){

                    deferred.reject(err)
                    }else{

                     deferred.resolve(body)
                      }

                 })

              return deferred.promise;            

        })


       Q.allSettled(promises).then((data)=>{
         var final_obj = {};
          for(var i = 0;i<data.length;i++){

              if(data[i].state == 'fulfilled'){

                  final_obj['val_'+i] = data[i].value; 

             }

          }
         writeFile(final_obj);


       })

}

loadIndicators()

 function writeFile(val){

   fs.writeFileSync('./data.json', util.inspect(val), 'utf-8');

  }