路由返回空数组,即使插入db似乎正常

时间:2019-02-13 12:26:58

标签: node.js node-sqlite3

我正在学习如何将Sqlite3与Node一起使用,并且遇到了一个奇怪的问题。在我的响应前端主App.js上的componentWillMount()中,我向路由/all发出了axios请求,以便可以填充联系人列表。

奇怪的是,当我添加其他联系人时,当我沿另一条路线/add发出了不同的axios请求时,它就这样到达了我的then()

axios
  .post('/add', contactData)
  .then(res =>
    console.log(`Contact ${contactData.name} added successfully`)
  )
  .catch(err => console.log('Error encountered: ', err));

还有一点延迟,因为我在发出axios请求之前设置了setState,这使我认为该联系人已添加到contacts表中。

但是当我直接访问localhost:5000/all时,我收到一个空数组[]作为响应。我不确定发生了什么。

这是我的server.js

const express = require('express');
const sqlite3 = require('sqlite3');
const path = require('path');
const cors = require('cors');

const dbName = 'my.db';
const tableName = 'Contacts';
const dbPath = path.resolve(__dirname, dbName);

const app = express();

const port = process.env.PORT || 5000;

app.use(cors());

app.listen(port, () => console.log(`Server running on port ${port}`));

app.get('/all', (req, res) => {
  let db = new sqlite3.Database(dbPath);

  let sql = `SELECT number FROM ${tableName}`;

  db.run(
    `CREATE TABLE IF NOT EXISTS ${tableName}(name text, number text, address text)`
  );

  db.all(sql, [], (err, rows) => {
    if (err) {
      return res.status(500).json(err);
    } else {
      return res.json(rows);
    }
  });
});

app.post('/add', (req, res) => {
  let db = new sqlite3.Database(dbPath);

  db.run(
    `INSERT INTO ${tableName}(name, number, address) VALUES(${req.name},${
      req.number
    },${req.address})`,
    [],
    err => {
      if (err) return res.status(500).json(err);
    }
  );

  return res.json({ msg: 'success' });
});

编辑:

我应该注意,当我导航到/ all时,会得到这个信息,

all

当我尝试发布到/ add时,出现错误消息

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

不,我在哪里发送多个回复。

3 个答案:

答案 0 :(得分:1)

您可以在Node.js中使用Async-Await解决此问题。 JavaScript本质上是异步的,Node也是如此。异步编程是一种确保无阻塞代码执行的设计模式。

非阻塞代码不会阻止一段代码的执行。通常,如果我们以同步方式执行,即一个接一个地执行,则不必要地停止了那些与您正在执行的代码无关的代码的执行。

异步与之完全相反,异步代码的执行没有任何依赖性和顺序。这样可以提高系统效率和吞吐量。

但是在某些情况下,我们需要等待响应。

 app.get('/all',async (req, res) => {
  let db = new sqlite3.Database(dbPath);
  let sql = `SELECT number FROM ${tableName}`;
 await db.run(
    `CREATE TABLE IF NOT EXISTS ${tableName}(name text, number text, address text)`
  );
 await  db.all(sql, [], (err, rows) => {
    if (err) {
      return res.status(500).json(err);
    } else {
      return res.json(rows);
    }
  });
});
app.post('/add',async  (req, res) => {
  let db = new sqlite3.Database(dbPath);
  await db.run(
    `INSERT INTO ${tableName}(name, number, address) VALUES(${req.name},${
      req.number
    },${req.address})`,
    [],
    err => {
      if (err) return res.status(500).json(err);
    }
  );
  return res.json({ msg: 'success' });
})

答案 1 :(得分:1)

每次点击/all时,我都不会初始化数据库并创建表。

尝试一下:

// get this out of the `/all` route, no need to initialize the db object over and over again
let db = new sqlite3.Database(dbPath);

// also leave this outside the `/all` route:
// no need to create the table over and over again.
db.run(
  `CREATE TABLE IF NOT EXISTS ${tableName}(name text, number text, address text)`
);


app.get('/all', (req, res) => {
  let sql = `SELECT number FROM ${tableName}`;

  // according to the sqlite3 api, the second parameter is optional, so just leave it out:
  db.all(sql, (err, rows) => {
    if (err) return res.status(500).json(err); // if you use return,  you don't need 'else' because the code will never reach it.

    res.json(rows)
  });
});

您的/add路线也看上去有些偏离。试试这个:

app.post('/add', (req, res) => {
  // let db = new sqlite3.Database(dbPath);  // remove this as you already defined it at the beginning of your code.

  db.run(
    `INSERT INTO ${tableName}(name, number, address) VALUES(${req.name},${req.number},${req.address})`,
    err => {
      if (err) return res.status(500).json(err);
      res.json({ msg: 'success' }); // put the success in the callback (after the query is run!), else, when you get an error, express.js will try to send an error message AND a success message giving you the error "Can't send headers after they are sent"
    }
  );

});

答案 2 :(得分:0)

await  db.all(sql, [], async (err, rows) => {
    if (err) {
       await return res.status(500).json(err);
    } else {
     await return res.json(rows);
    }
  });