mysql Node : can't set headers after they are sent

标签 mysql node.js express

我正在尝试获取目录中的电影列表,解析标题,在 TMDB 上获取电影信息,然后检查电影信息是否存储在 mysql 数据库中,以及是否未存储,将信息插入数据库。

我正在使用NodeJS/Expressmysql

这是迄今为止我的代码:

exports.checkForMovies = function (req, res, next) {
  const testFolder = './test/';
  var movieList = [];
  var movieResultsPromise = [];
  var movieResults = [];

  fs.readdirSync(testFolder).forEach(file => {
    movieList.push(tnp(file));
  });

  movieList.forEach(movie => {
    var waitPromise = searchTMDB(movie.title);
    movieResultsPromise.push(waitPromise);
  });

  Promise.all(movieResultsPromise).then(result => {
    movieResults = result;

    movieResults.forEach(movie => {
      checkMoviesInDB(movie.id, (err, data) => {
        if (err) {
          console.log(err)
        }

        if (data && data.update === true) {

          var movieObj = {
            m_tmdb_id: movie.id
          };

          insertMoviesToDB(movieObj, (resp, err) => {
            if (err) {
              console.log(err);
            } else {
              return res.json(resp);
            }
          });
        } else {
          return res.json(data);
        }
      });
    });
  });
}

function checkMoviesInDB(id, cb) {
  var sql = "SELECT * FROM ?? WHERE m_tmdb_id = ?"
  var table = ['movie', id];

  sql = mysql.format(sql, table);

  connection.query(sql, function (err, rows) {
    if (err) {
      return cb(err);
    }

    if (rows.length > 0) {
      return cb(null, {
        success: true,
        update: false,
        message: 'Movies up to date!'
      })
    } else {
      return cb(null, {
        update: true,
        message: 'Updating database!'
      })
    }
  });
}

function insertMoviesToDB(movie, cb) {
  var sql = "INSERT INTO ?? SET ?";
  var table = ['movie', movie];

  sql = mysql.format(sql, table);

  connection.query(sql, function (err, rows) {
    if (err) {
      return cb(err);
    } else {
      return cb(null, {
        success: true,
        message: 'Movie database updated!'
      })
    }
  });
}

function searchTMDB(title) {
  return new Promise((resolve, reject) => {
    https.get(config.tmdbURL + title, response => {
      var body = "";
      response.setEncoding("utf8");

      response.on("data", data => {
        body += data;
      });
      response.on("end", () => {
        body = JSON.parse(body);
        resolve(body.results[0]);
      });
      response.on("error", (err) => {
        reject(err);
      });
    });
  });
}

代码执行后,它会在数据库中插入电影信息或使用“最新电影”进行响应,但我收到此错误并且 NodeJS 崩溃:

Error: Can't set headers after they are sent.

感谢任何帮助,谢谢!

编辑!

这是新代码,我仍然遇到相同的错误...

exports.checkForMovies = function (req, res) {
  const testFolder = './test/';
  var movieList = [];
  var movieResults = [];

  fs.readdirSync(testFolder).forEach(file => {
    movieList.push(tnp(file));
  });


  var movieObj = movieList.map(movie => {
    var tmp = [];
    return searchTMDB(movie.title).then(data => {
      tmp.push(data);
      return tmp
    });
  });

  var checkDB = Promise.all(movieObj).then(moviesData => {
    moviesData.map(movieData => {
      checkMoviesInDB(movieData[0]).then(checkResponse => {
        if (!checkResponse.movieToInsert) {
          res.json(checkResponse);
        } else {
          var insertArray = checkResponse.movieToInsert;
          var inserting = insertArray.map(movie => {

            var movieObject = {
              m_tmdb_id: movie.id,
              m_name: movie.title,
              m_year: movie.release_date,
              m_desc: movie.overview,
              m_genre: undefined,
              m_poster: movie.poster_path,
              m_watched: 0
            };

            insertMoviesToDB(movieObject).then(insertResponse => {
              res.json(insertResponse);
            });
          });
        }
      });
    });
  });
}

function checkMoviesInDB(movie) {
  var moviesToInsert = [];

  return new Promise((resolve, reject) => {
    var sql = "SELECT * FROM ?? WHERE m_tmdb_id = ?"
    var table = ['movie', movie.id];

    sql = mysql.format(sql, table);

    connection.query(sql, function (err, rows) {
      if (err) {
        return reject(err);
      }

      if (rows.length === 0) {
        moviesToInsert.push(movie);
        resolve({
          success: true,
          movieToInsert: moviesToInsert
        });
      } else {
        resolve({
          success: true,
          message: 'No movie to insert'
        });
      }
    });
  });
}

function insertMoviesToDB(movie) {
  return new Promise((resolve, reject) => {
    var sql = "INSERT INTO ?? SET ?";
    var table = ['movie', movie];

    sql = mysql.format(sql, table);

    connection.query(sql, function (err, rows) {
      if (err) {
        return reject(err);
      } else {
        resolve({
          success: true,
          message: 'Movie added!'
        });
      }
    });
  });
}

function searchTMDB(title) {
  return new Promise((resolve, reject) => {
    https.get(config.tmdbURL + title, response => {
      var body = "";
      response.setEncoding("utf8");

      response.on("data", data => {
        body += data;
      });
      response.on("end", () => {
        body = JSON.parse(body);
        resolve(body.results[0]);
      });
      response.on("error", (err) => {
        reject(err);
      });
    });
  });
}

Auth.js

const config = require('./config');
const jwt = require('jsonwebtoken');

module.exports = function (req, res, next) {

    var token = req.body.token || req.params.token || req.headers['x-access-token'];

    if (token) {
        jwt.verify(token, config.secret, function (err, decoded) {
            if (err) {
                return res.json({
                    success: false,
                    message: 'Failed to authenticate token.'
                });
            } else {
                req.decoded = decoded;
                next();
            }
        });
    } else {
        return res.status(403).send({
            success: false,
            message: 'Please login in to countinue!'
        });
    }

};

最佳答案

希望这有帮助:

// Bad Way
const checkForMovies = (req, res) => {
  const movieList = ['Braveheart', 'Highlander', 'Logan'];
  movieList.forEach(movie => {
    res.json(movie);   // Will get Error on second loop: Can't set headers after they are sent.
  })
}

// Good Way
const checkForMovies = (req, res) => {
  const movieList = ['Braveheart', 'Highlander', 'Logan'];
  const payload = { data: { movieList: [] } };
  movieList.forEach(movie => {
    payload.data.movieList.push(movie);
  });
  // send res once after the loop with aggregated data
  res.json(payload);
}

/* GET home page. */
router.get('/', checkForMovies);

关于mysql Node : can't set headers after they are sent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49095037/

相关文章:

mysql - MySql索引(B+树)中的指针如何保持有效,而索引可以存储在磁盘中并返回到另一个页面?

mysql - Wamp phpMyAdmin密码问题

javascript - 为什么我的 Node Express 应用程序无法从 Mongoose 获取数据?

MySql 多对多仅选择连接行处的固定行

mysql - 存储过程还是 View ?

Node.js 异步 |从 api 插入 postgresql 数据库结果

node.js - Node.js 事件循环的概念与 CICS 伪对话式编程相同吗?

javascript - 什么是 express.json() 和 express.urlencoded()?

node.js - Nginx - 源服务器响应代码为 401 时的速率限制

javascript - 我怎样才能在端口 80 上使用 node.js 提供单页 html?