Node.js file blocks terminal after correct execution

Issue

I’m new to using Node and fetch and of course I’m having some problems with my code. Essentially I’m trying to implement a project where I get some json data through an API request and store it into a mysql database. These data is contained in multiple pages and therefore I used a simple for cycle for multiple fetching. I do this 2 times as I have to get data from 2 different object lists. For storing the data I first established a mysql connection and later I execute the sql query inside another for iterating the single object data.
It performes correctly both extraction of json data and storage in mysql database but once I execute node index.js on the terminal, the process keeps on running and the terminal gets suspended until I force the process to terminate.
I used why-is-node-running and found out this:enter image description here

Here’s the code of index.js:

import mysql from 'mysql';
import fetch from 'node-fetch';
import log from 'why-is-node-running';

const URL0 = "https://atlas.ripe.net/api/v2/probes/?status=1";
const sql = "INSERT INTO probes (id, country, longitude, latitude) VALUES (?,?,?,?)";
const sql1 = "INSERT INTO anchors (id, country, longitude, latitude) VALUES (?,?,?,?)";
const PG_SIZE = 100;
let num_pages_probes=120;
let i=0, j=1, k=1, a=0;

const con = mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'',
    database:'probes&anchors'
});

        
con.connect((err)=>{
    if(err){
        console.log("Connection not proper");
    }else{
        console.log("connected");
    }
});
/*
fetch(URL0)
    .then((response) => {
      if (!response.ok) {
          throw new Error("HTTP error! status: "
          + response.status);
          } else {
          return response.json();
          }
    })
.then((data) => {

    num_pages_probes = Math.ceil(data.count/PG_SIZE);
    console.log(num_pages_probes);
});
*/
for (j; j<=2; j++){
    console.log("j="+j);
    let URLi = "https://atlas.ripe.net/api/v2/probes/?page="+j+"&status=1";
    fetch(URLi)
    .then((response) => {
      if (!response.ok) {
          throw new Error("HTTP error! status: "
          + response.status);
          } else {
          return response.json();
          }
    })
    .then((data) => {

        for (let probe of data.results){
            i++;
            let id0 = probe.id;
            let country = probe.country_code;
            let longitude = probe.geometry.coordinates[0];
            let latitude = probe.geometry.coordinates[1];
            
            con.query(sql, [id0, country, longitude, latitude], function (err, result) {
                if (err) throw err;
                console.log("1 record inserted");
            });
    
            console.log("id0: "+id0+"\t"+"cc: "+country+"\t"+"long: "+longitude+"\t"+"lati: "+latitude);
            console.log(i);
        }
      //  con.end();

    });
}



for (k; k<=2; k++){
    console.log("k="+k);
    let URLi = "https://atlas.ripe.net/api/v2/anchors/?page="+k;
    fetch(URLi)
    .then((response) => {
      if (!response.ok) {
          throw new Error("HTTP error! status: "
          + response.status);
          } else {
          return response.json();
          }
    })
    .then((data) => {

        for (let anchor of data.results){
            a++;
            let id0 = anchor.id;
            let country = anchor.country;
            let longitude = anchor.geometry.coordinates[0];
            let latitude = anchor.geometry.coordinates[1];
            
            con.query(sql1, [id0, country, longitude, latitude], function (err, result) {
                if (err) throw err;
                console.log("1 record inserted");
            });
            
            console.log("id0: "+id0+"\t"+"cc: "+country+"\t"+"long: "+longitude+"\t"+"lati: "+latitude);
            console.log(a);
        }

    });
}

setTimeout(function () {
    log() // logs out active handles that are keeping node running
  }, 100)

Can someone help me out please? I don’t know where to put my hands on.
PS. I purposely limited the cycle to 2 but it would actually be like 120.

Solution

You are not closing your mysql connection which keep your proccess up.

You probably want to close your connection when all your fetch/inserts are done, the tricks here is to ensure you’ve completed all your inserts before closing your connection.

You can have a look at async/await syntax, it will help you ensure you are closing only when you’ve done your inserts.

A very simplified version would look like:

const fn = async () => {
  const con = mysql.createConnection({ ... });
  for (...) {
    const res = await fetch({ ... });
    const data = await res.json();
    await con.query({ ... });
  }
  await con.close();
}
fn();

NOTE: The mysql lib seems to only work with callback, so you will probably have to promisify the methods you need (see utils.promisify)

Answered By – shantr

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published