Обещание SQL в NodeJS возвращает пустые скобки, но когда тот же запрос выполняется в рабочей среде SQL, он возвращает правильные данные - PullRequest
0 голосов
/ 07 октября 2019

У меня есть некоторый код в NodeJS, предназначенный для приложения React. Его цель очень проста. Выполнить запрос SELECT MySQL и вернуть правильные данные. Тем не менее, я столкнулся с несколькими проблемами с ним. Во-первых, я должен был сделать это асинхронным запросом, что я и сделал. Однако, когда я записываю окончательный ответ в консоли, я получаю объект данных.

Query {
  domain: null,
  _events:
   { error: [Function],
     packet: [Function],
     timeout: [Function],
     end: [Function] },
  _eventsCount: 4,
  _maxListeners: undefined,
  _callback: undefined,
  _callSite: Error
    at Protocol._enqueue (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\node_modules\mysql\lib\protocol\Protocol.js:144:48)
    at Connection.query (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\node_modules\mysql\lib\Connection.js:201:25)
    at Promise (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\src\api\main.js:25:21)
    at new Promise (<anonymous>)
    at getResult (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\src\api\main.js:24:21)
    at C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\src\api\main.js:38:16
    at Layer.handle [as handle_request] (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Users\Anirudh\Desktop\Books Searcher\book-searcher\node_modules\express\lib\router\layer.js:95:5),
  _ended: false,
  _timeout: undefined,
  _timer: Timer { _object: [Circular], _timeout: null },
  sql: 'SELECT * FROM books_catalouge WHERE Author = "Alex Scarrow"',
  values: undefined,
  typeCast: true,
  nestTables: false,
  _resultSet: null,
  _results: [],
  _fields: [],
  _index: 0,
  _loadError: null,
  _connection:
   Connection {
     domain: null,
     _events: {},
     _eventsCount: 0,
     _maxListeners: undefined,
     config:
      ConnectionConfig {
        host: 'localhost',
        port: '3306',
        localAddress: undefined,
        socketPath: undefined,
        user: 'root',
        password: 'pokemon2345',
        database: 'my_books',
        connectTimeout: 10000,
        insecureAuth: false,
        supportBigNumbers: false,
        bigNumberStrings: false,
        dateStrings: false,
        debug: undefined,
        trace: true,
        stringifyObjects: false,
        timezone: 'local',
        flags: '',
        queryFormat: undefined,
        pool: undefined,
        ssl: false,
        multipleStatements: false,
        typeCast: true,
        maxPacketSize: 0,
        charsetNumber: 33,
        clientFlags: 455631 },
     _socket:
      Socket {
        connecting: true,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 7,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: false,
        _bytesDispatched: 0,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        _idleTimeout: 10000,
        _idleNext: [Object],
        _idlePrev: [Object],
        _idleStart: 16067,
        _destroyed: false,
        [Symbol(asyncId)]: 16,
        [Symbol(bytesRead)]: 0,
        [Symbol(asyncId)]: 20,
        [Symbol(triggerAsyncId)]: 13 },
     _protocol:
      Protocol {
        domain: null,
        _events: [Object],
        _eventsCount: 7,
        _maxListeners: undefined,
        readable: true,
        writable: true,
        _config: [Object],
        _connection: [Circular],
        _callback: null,
        _fatalError: null,
        _quitSequence: null,
        _handshake: true,
        _handshaked: false,
        _ended: false,
        _destroyed: false,
        _queue: [Array],
        _handshakeInitializationPacket: null,
        _parser: [Object] },
     _connectCalled: true,
     state: 'disconnected',
     threadId: null } }

Очевидно, что есть какая-то ошибка, но когда я использую оператор try, он просто пропускает улов. Что более того, когда я отправляю его в само приложение React, оно выглядит как строка из пустых цветочных скобок! "{}". Я понятия не имею, что происходит. Вот мой код NodeJS: -

app.get("/retrieve_books", function(req, res) {
  async function getResult(sql) {
    var con = mysql.createConnection({
      host: "localhost",
      port: "3306",
      database: "my_books",
      user: "root",
      password: "pokemon2345"
    });
    con.connect();
    try {
      let promise = new Promise((resolve, reject) => {
        resolve(con.query(sql));
      });
      var answer = await promise;
      console.log("answer");
    } catch (err) {
      console.log(err);
    }
    con.end();
    return answer;
  }

  var sql = JSON.parse(req.query.msg);
  console.log(sql);
  var answer = getResult(sql);
  console.log(answer);
  res.send(JSON.stringify(answer));
});

Вот мой код React: -

import React, { useState } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Form from "./searcherFormDumb";
import { toast } from "react-toastify";

function Searcher() {
  const [book, setBook] = useState({
    name: "",
    author: "",
    sno: null,
    series: "",
    type: "",
    genre: "",
    kindleReal: ""
  });
  const defaultState = {
    name: "",
    author: "",
    sno: null,
    series: "",
    type: "",
    genre: "",
    kindleReal: ""
  };

  function handleChange(event) {
    const updatedBook = { ...book, [event.target.name]: event.target.value };
    setBook(updatedBook);
  }

  function handleSubmit(event) {
    event.preventDefault();
    var changed = {};
    function populateChanged(now, old, title, temp) {
      if (now !== old) {
        temp[title] = now;
        return temp;
      } else {
        return temp;
      }
    }
    changed = populateChanged(
      book.name,
      defaultState.name,
      "Book_Name",
      changed
    );
    changed = populateChanged(
      book.author,
      defaultState.author,
      "Author",
      changed
    );
    changed = populateChanged(book.sno, defaultState.sno, "S_no", changed);
    changed = populateChanged(
      book.series,
      defaultState.series,
      "Series_Name",
      changed
    );
    changed = populateChanged(
      book.type,
      defaultState.type,
      "Fiction_Non_fiction_Companion_Prequel",
      changed
    );
    changed = populateChanged(book.genre, defaultState.genre, "Genre", changed);
    changed = populateChanged(
      book.kindleReal,
      defaultState.kindleReal,
      "Kindle_Real",
      changed
    );
    var temp_string = "";
    var key = "";
    var value = "";
    var temp_string_list = [];
    //debugger;
    for (var i = 0; i < Object.keys(changed).length; i++) {
      //debugger;
      key = Object.keys(changed)[i];
      value = changed[key];
      if (i !== Object.keys(changed).length - 1) {
        temp_string = `${key} = "${value}" AND `;
      } else if (i === Object.keys(changed).length - 1) {
        temp_string = `${key} = "${value}"`;
      }
      temp_string_list.push(temp_string);
      //debugger;
      temp_string = "";
      key = "";
      value = "";
    }

    var sql_t = temp_string_list.join("");
    var sql_tt = "SELECT * FROM books_catalouge WHERE ";
    var sql = sql_tt + sql_t;
    toast.success(sql);

    var request = new XMLHttpRequest();
    var jsql = JSON.stringify(sql);
    request.onreadystatechange = function() {
      //debugger;
      if (this.readyState == 4 && this.status == 200) {
        var response = this.responseText;
        console.log(typeof response);
      }
    };
    request.open(
      "GET",
      "http://localhost:3001/retrieve_books" + "?msg=" + jsql,
      true
    );
    request.send(jsql);
    console.log("This is the END");
  }

  return (
    <>
      <Form book={book} onChange={handleChange} onSubmit={handleSubmit} />
    </>
  );
}

export default Searcher;

Если вам потребуется дополнительная информация, пожалуйста, не стесняйтесь спрашивать. Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 07 октября 2019

Есть несколько проблем. Я думаю, что они проистекают из сложности, присущей этому коду.

  1. getResult возвращает обещание, но не await d или then d.

    var answer = getResult (sql);console.log (ответ);res.send (JSON.stringify (answer));

getResult возвращает обещание. вам нужно будет сделать

const answer = await getResult(sql);

или

getResult(sql)
  .then(JSON.stringify)
  .then(result => res.send(result))
Разрешение обещания в getResult не работает так, как вы ожидаете

Я бы упростил это, чтобы начать и строить оттуда. Что-то вроде этого хорошо

app.get("/retrieve_books", function(req, res) {
  var con = mysql.createConnection({
    host: "localhost",
    port: "3306",
    database: "my_books",
    user: "root",
    password: "pokemon2345"
  });
  con.connect();
  con.query(sql, (err, result) => {
    if (err) {
      console.error(err);
      res.send(500, 'omgz');
    }
    res.send(result);
    return con.end();
  });
});

Отсюда вы можете посыпать обещаниями и асинхронно / ждать.

2 голосов
/ 07 октября 2019

Похоже, что при работе с асинхронными функциями в вашем коде возникают некоторые проблемы.

  1. Ваш обработчик get запроса также должен быть async функцией и использовать await для асинхронных функций.
  2. Обещание внутри getResult должно быть разрешено, как con.query(sql, resolve)

Попробуйте этот вариант.

app.get("/retrieve_books", async function(req, res) {
  async function getResult(sql) {
    var con = mysql.createConnection({
      host: "localhost",
      port: "3306",
      database: "my_books",
      user: "root",
      password: "pokemon2345"
    });
    con.connect();
    try {
      let promise = new Promise((resolve, reject) => {
        con.query(sql, (error, results) => resolve(results));
      });
      var answer = await promise;
      console.log("answer");
    } catch (err) {
      console.log(err);
    }
    con.end();
    return answer;
  }

  var sql = JSON.parse(req.query.msg);
  console.log(sql);
  var answer = await getResult(sql);
  console.log(answer);
  res.send(JSON.stringify(answer));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...