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.