Борьба с цепочкой postgres db async / await обещает получить результат, отправленный клиенту (express) - PullRequest
0 голосов
/ 19 апреля 2020

Я потратил некоторое время на просмотр подобных проблем в Интернете, но мне, кажется, действительно трудно обдумать это. Я просмотрел несколько источников в Интернете за помощью, но не смог применить логи c, которые я видел, к моей собственной кодовой базе, я надеюсь, что кто-то там сможет помочь.

Я бегу сервер express с пулом pg для обработки логики БД c.

Я могу успешно выйти из системы из логики pg.Pool c, несмотря на то, что ударился головой о несколько попыток Мне не удалось успешно передать данные на клиентскую сторону.

dbQueries. js


const { Pool } = require('pg');

const pool = new Pool({
  user: process.env.DB_USER,
  host: process.env.DB_HOST,
  database:process.env.DB_NAME,
  password: process.env.DB_PASSWORD,
  port: process.env.DB_PORT
});

// Main function called in server.js
// step 1. fetches distinct name values from pg table
// step 2. fetches values to get full list of reviews for those distinct names
// step 3. does some data modification to make the data formatted for frontend usecase

const getFormattedReviews = async function(){
  console.log('Fetching all unique therapist review names.')

  const getDistinct = {
    name: 'distinct-reviews',
    text: 'SELECT DISTINCT therapist_name FROM reviews'
  };

  // step 1
  const res = await pool.query(getDistinct, (err, res) => {
    let data = []
    if (err) {
      console.log(err.stack);
    } else {
      // console.log(res.rows);
      data = res.rows.map(
        // step 2
        therapist => getSpecificTherapistReviews(therapist.therapist_name)
      )
    }
    console.log(`\n DEBUG3 - getFormattedReviews data: ${JSON.stringify(data)} \n`)
    return data;
  });
  return res;
}

const getSpecificTherapistReviews = async function(therapist_name){
  console.log(`Fetching reviews for: ${therapist_name}.`)

  const getSpecificTherapistReviews = {
    name: `${therapist_name}-reviews`,
    text: `SELECT * FROM reviews WHERE therapist_name LIKE '%${therapist_name}%'`
  };

  const res = await pool.query(getSpecificTherapistReviews, (err, res) => {
    let data = []
    if (err) {
      console.log(err.stack);
    } else {
      // console.log(res.rows);
      // step 3
      data = filteringDataForFrontend(res.rows);
    }
    console.log(`\n DEBUG2 - GetSpecificTherapistReviews ${JSON.stringify(data)} \n`)
    return data;
  });
  return res;
}

const filteringDataForFrontend = function(data){
  console.log(`Filtering Data for Frontend.`)

  // Based on length of the reviews array, each review = 1 object
  const total_reviews = data.length;

  // Underlying logic assumes consistent data across all entries for these values
  const therapist_name = data[0].therapist_name;
  const type = data[0].type;
  const image = data[0].image;
  const location = data[0].location;

  // Summing the rating values across multiple review entries
  const ratings = data.reduce((acc, obj) => ({
    rating_friendliness: acc.rating_friendliness + obj.rating_friendliness,
    rating_techniques: acc.rating_techniques + obj.rating_techniques,
    rating_progression: acc.rating_progression + obj.rating_progression,
    rating_cost: acc.rating_progression + obj.rating_progression,
    rating_listening: acc.rating_listening + obj.rating_listening,
    rating_overall: acc.rating_overall + obj.rating_overall
    })
  )

  // Placeholder as string, most likely restructure to an array of objects
  const comments = data.reduce ((acc, obj) => ({
      feedback_comments: acc.feedback_comments + obj.feedback_comments
    })
  )

  // Filtered data for returning
  const filteredData = {
    therapist_name,
    type,
    image,
    location,
    rating_friendliness: ratings.rating_friendliness / total_reviews,
    rating_techniques: ratings.rating_techniques / total_reviews,
    rating_progression: ratings.rating_progression / total_reviews,
    rating_cost: ratings.rating_cost / total_reviews,
    rating_listening: ratings.rating_listening / total_reviews,
    rating_overall: ratings.rating_overall / total_reviews,
    feedback_comments: comments.feedback_comments
  }
  console.log(`\n DEBUG 1 - filteredData -> ${JSON.stringify(filteredData)} \n`)
  return filteredData;
}

module.exports = {
  getFormattedReviews,
};

Идеальная настройка, которую я хотел бы иметь на сервере. js сторона все, что работает express будет:

сервер. js

const express = require('express');
const DB = require('./dbQueries.js');
const app = express();
const port = process.env.SERVER_PORT || 8000;

app.get('/get-reviews', async (req, res) => {
  const data = await DB.getFormattedReviews();
  console.log(`data check ${data}`);
  res.send({data});
});

В настоящее время конечная точка регистрирует «проверка данных не определена».

Проверка отладки 1 и 2 успешно появляются для регистрации информации, однако я заметил, что DEBUG 3 только регистрирует DEBUG3 - getFormattedReviews data: [{},{},{}], так что, возможно, я что-то там не так делаю?

Любая помощь / понимание приветствуется.

Ответы [ 2 ]

0 голосов
/ 19 апреля 2020

Спасибо @Abraham & @Labkovsky за предложения -> Я проверю их должным образом в течение недели.

Мне удалось настроить базовую функциональность c и запустить ее с этим кодом - он, вероятно, нуждается в некотором рефакторинге, но для справки:

dbQueries. js

const getFormattedReviews = async function(){

  const getDistinct = {
    name: 'distinct-reviews',
    text: 'SELECT DISTINCT therapist_name FROM reviews'
  };

  const res = await new Promise(resolve => {
    pool.query(getDistinct, (err, res) => {
    let data = []
    if (err) {
      console.log(err.stack);
    } else {
      // console.log(res.rows);
      data = res.rows.map(
        async therapist => await getSpecificTherapistReviews(therapist.therapist_name)
      )
      // Promise.all(data).then(results => console.log(`\n DEBUG3 - getFormattedReviews data: ${JSON.stringify(results)} \n`))
    }
    Promise.all(data).then(results => resolve(results));
  });

});
  return res;
}

const getSpecificTherapistReviews = async function(therapist_name){
  // console.log(`Fetching reviews for: ${therapist_name}.`)

  const getSpecificTherapistReviews = {
    name: `${therapist_name}-reviews`,
    text: `SELECT * FROM reviews WHERE therapist_name LIKE '%${therapist_name}%'`
  };

  const res = await new Promise(resolve => {
    pool.query(getSpecificTherapistReviews, (err, res) => {
      let data = []
      if (err) {
        console.log(err.stack);
      } else {
        // console.log(res.rows);
        data = filteringDataForFrontend(res.rows);
      }
      // console.log(`\n DEBUG2 - GetSpecificTherapistReviews ${JSON.stringify(data)} \n`)
      resolve(data);
    });
  });
  return res;
}

const filteringDataForFrontend = function(data){
  // Based on length of the reviews array, each review = 1 object
  const total_reviews = data.length;

  // Underlying logic assumes consistent data across all entries for these values
  const therapist_name = data[0].therapist_name;
  const type = data[0].type;
  const image = data[0].image;
  const location = data[0].location;

  // Summing the rating values across multiple review entries
  const ratings = data.reduce((acc, obj) => ({
    rating_friendliness: acc.rating_friendliness + obj.rating_friendliness,
    rating_techniques: acc.rating_techniques + obj.rating_techniques,
    rating_progression: acc.rating_progression + obj.rating_progression,
    rating_cost: acc.rating_progression + obj.rating_progression,
    rating_listening: acc.rating_listening + obj.rating_listening,
    rating_overall: acc.rating_overall + obj.rating_overall
    })
  )

  // Placeholder as string, most likely restructure to an array of objects
  const comments = data.reduce ((acc, obj) => ({
      feedback_comments: acc.feedback_comments + obj.feedback_comments
    })
  )

  // Filtered data for returning
  const filteredData = {
    therapist_name,
    type,
    image,
    location,
    total_reviews,
    rating_friendliness: ratings.rating_friendliness / total_reviews,
    rating_techniques: ratings.rating_techniques / total_reviews,
    rating_progression: ratings.rating_progression / total_reviews,
    rating_cost: ratings.rating_cost / total_reviews,
    rating_listening: ratings.rating_listening / total_reviews,
    rating_overall: ratings.rating_overall / total_reviews,
    feedback_comments: comments.feedback_comments
  }

  // console.log(`\n DEBUG 1 - filteredData -> ${JSON.stringify(filteredData)} \n`)
  return filteredData;
}

module.exports = {
  getFormattedReviews,
};

server. js

const express = require('express');
const DB = require('./dbQueries.js');
const app = express();
const port = process.env.SERVER_PORT || 8000;

app.get('/get-reviews', async (req, res) => {
  const data = await DB.getFormattedReviews();
  // data.then(data => console.log(`data2 check ${JSON.stringify(data)}`))
  res.send(data);

});

В конечном счете, я думаю, что мое ограниченное понимание Promises / Async / Await & Promise.all меня здесь немного подвело, Promise.all в getFormattedReviews был недостающим приемом.

Часть кода была переписана с использованием какого-то нового синтаксиса Promise, который, вероятно, можно отредактировать, однако я заметил, что при выполнении этого с помощью метода getFormattedReviews он прервал отправку данных в конечную точку / get-reviews. Что-то, что я исследую позже.

0 голосов
/ 19 апреля 2020

Вы ожидаете обратного вызова. Я не думаю, что это работает.

Попробуйте обернуть в Обещание. Это может быть проблемой.

Полное раскрытие: я не очень внимательно прочитал ваш код ...

const res = await new Promise(resolve => {
pool.query(getSpecificTherapistReviews, (err, res) => {
    let data = []
    if (err) {
      console.log(err.stack);
    } else {
      // console.log(res.rows);
      // step 3
      data = filteringDataForFrontend(res.rows);
    }
    console.log(`\n DEBUG2 - GetSpecificTherapistReviews ${JSON.stringify(data)} \n`)
    resolve(data);
  });
})
...