简体   繁体   中英

How can I make multiple API calls to save all results in one json file using Nodejs?

I want to fetch results from a JSON API for different urls (values) in one go and save results in one json file. My approach is the following, but I am stuck with pending Promises in my resulting object and json file. Is there any way I can solve this using Promises, or shall I use callbacks? Any hint is greatly appreciated. I am sure that can be coded much better.

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

Your getIndicator and loadIndicators function could return Promise so you can do Promise.all in loadIndicators loop.

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

You can wait for all your promises to be resolved and each resolve will add the JSON to a global variable or a file. This may be tricky w/o using a promise library.

I would suggest using bluebird or any other alternative. Specifically for your problem check out promise.all API of bluebird.

It think it will be more simple one

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

  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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