I want to use Axios + nedb in a NodeJS Script to gather data from an API into a local file. This is what I done so far:
var axios = require('axios');
var Datastore = require('nedb');
const fs = require('fs');
db = new Datastore({ filename: './../smb_share/art.db', autoload: true });
function getArt(limit, offset) {
var config = {
method: 'get',
url: 'http://IPADD/api/data/2:1/?limit=' + limit + '&offset=' + offset',
headers: {
'Accept': 'application/simple+json',
'Content-Type': 'application/json',
'Authorization': 'Basic XYZ'
}
};
axios(config)
.then(function (response) {
response.data.erpDataObjects.forEach(element => {
var doc = { number:element.head.number,
desc:element.head.desc
};
db.insert(doc, function (err, newDoc) {
if(err =! null){
console.log(err);
}
});
});
})
.catch(function (error) {
console.log(error);
});
}
getArt(1000,0)
getArt(1000,1000)
This works fine, as long I am not gathering more data from the API. I need to call my function "getArt(limit, offset)" round about 400 times, because I get about 400000 docs from the API. I tried to do this with intervalTimers, so start every 5min the function and ++offset with 1000 each time the interval event is fired... Yes, I know that's weird, but it was the only way which worked for me at the moment. But when the API server is on heavy load, it takes too long for one query and I exceed the limit of call which end up in a mess.
My Question: how do I keep things clear and fire the functions when the function before is ready? I tried a lot of async/await stuff, but all ended up in errors or all was fired at the same time. What I basically need is something like ...
getArt(10000,0)
.then
getArt(10000,10000)
.then
getArt(10000,20000)
.then
...
But with the nested function of axios I don't know how to handle this with a promise. Can someone give me a hint?
Have you tried making getArt
an async function
and simply awaiting
it?
async function getArt(limit, offset){...}
async function Name(){
await getArt(10000, 1000); // wait to complete before moving on
await getArt(10000, 2000); // only execute when above is done
}
Name();
By not assigning the result of await
, you simply tell your program to wait for this function to complete prior to moving on to next one.
Side Note:
Why not make a for loop which increments the offset and calls the getArt
function?
async function Name(){
var limit = 10000;
for(let offset = 0; offset < limit; offset += limit/10){
await getArt(limit, offset);
}
}
Name();
I haven't tested this, but see no reason why it should not work.
Additionally, (to follow good practice guidelines) you should wrap your await
statements in a try-catch
block to deal with errors like so:
try{
await getArt(limit, offset);
}
catch(err){
console.error(err);
}