asynchronous and synchronous problem in javascript

this should give me the average windspeed. However, the table is created before the average windspeeds are pushed to the array. How can i fix this? The purpose of the code is to first push the average windspeeds to the table array, and then return this variable. When I run this code, it first returns me all the "NaN" of the minute loop, in between the table and then the ‘afterfileread’ values.

const express = require('express');
const windRouter = express.Router()
const fs = require('fs')
const {
  readdirSync
} = require('fs')

windRouter.get('', (req, res) => {
  res.render('winddata', {
    weatherdata: null
  })
});

windRouter.get('/:id/:date', async(req, res) => {
  console.log("station nr: " + req.params.id);
  console.log("datum: " + req.params.date);
  try {
    var table = await getWeatherTable(req.params.id, req.params.date);
    //res.json(table);
    res.render("winddata", {
      weatherdata: table
    })
  } catch (err) {
    if (err.response) {
      res.render('winddata', {
        weatherdata: null
      })
      console.log(err.response.data)
      console.log(err.response.status)
      console.log(err.response.header)

    } else if (err.requiest) {
      res.render('winddata', {
        weatherdata: null
      })
      console.log(err.requiest)

    } else {
      res.render('winddata', {
        weatherdata: null
      })
      console.log('errore', err.message)
    }
  }
});


const getDirectories = source =>
  readdirSync(source, {
    withFileTypes: true
  })
  .filter(dirent => dirent.isDirectory())
  .map(dirent => dirent.name)

const average = (array) => array.reduce((a, b) => a + b) / array.length;

async function getWeatherTable(id, date) {

  var stnNR = id;
  var table = []

  const dates = date.split('-');
  var year = dates[0]
  var month = dates[1]
  var day = dates[2]

  var hours = getDirectories(`./Data/${year}/${month}/${day}/`);
  hours.forEach(async(hour) => {
    var windspeeds = ["NaN"];

    const minutes = getDirectories(`./Data/${year}/${month}/${day}/${hour}/`)
    minutes.forEach((minute) => {
      fs.readFile((`./Data/${year}/${month}/${day}/${hour}/${minute}/${stnNR}.json`), 'utf8', (err,
        jsonString) => {
        if (err) {
          console.log(err)
        } else {
          const data = JSON.parse(jsonString);
          windspeeds.push(parseInt((data.MEASUREMENT.WDSP)));
          console.log("afterfileread: " + windspeeds)
        }
      });
      console.log("inside minute loop: " + windspeeds)
    });
    console.log("outside minute loop: " + windspeeds)

    Promise.all(windspeeds).then(() => {
      const gemspeed = average(windspeeds);
      console.log("gemspeed for hour: " + hour + " " + gemspeed);
      table.push({
        "hour": hour + ":00",
        "speed": gemspeed
      });
    });

  });

  // Promise.all(table).then(() =>{
  //     table.push({"hour": "Error", "speed": "could not calculate"})
  //     console.log("promise is kept if table is afther this line is equal to the webpage ")
  //     console.log("table:");
  //     console.log(table);

  // });
  return table
}

module.exports = windRouter

80 thoughts on “asynchronous and synchronous problem in javascript”

Leave a Comment