首页 > 解决方案 > 未定义的变量异步 JavaScript

问题描述

我刚开始学习 Node.js / Express,但我仍然无法使用异步功能。我制作了一些函数来与 postgresql 数据库交互(带有一些教程),并且从数据中选择行很好,但由于某种原因,删除行会发生一些事情。这是一个运行良好的函数示例:

const getPlayers = () => {
 return new Promise(function(resolve, reject) {
  pool.query('SELECT * FROM Players ORDER BY p_id ASC', (error, results) => {
    if (error) {
      reject(error)
    }
    resolve(results.rows);
  })
 }) 
}

现在下面的功能并不顺利。Console.log(id) 给出了正确的数字,但执行查询时似乎未定义 id,我怀疑它与异步/同步有关。现在异步对我来说是新的,所以我也不是什么问题的专家。这是运行良好的功能:

const deletePlayer = (id) => {
 return new Promise(function(resolve, reject) {
  pool.query('DELETE FROM Players WHERE player_id = ?' , [id], (error,results) => {
   if (error) {
    reject(error)
   }
   resolve(`Player deleted with ID: ${id}`)
   })
  })
 }

函数调用:

app.delete('/laProjects/:id', (req, res) => {
players_model.deletePlayers(req.params.id)
.then(response => {
 res.status(200).send(response);
 })
.catch(error => {
 res.status(500).send(error);
 })
})

标签: javascriptsqlnode.jsexpressasynchronous

解决方案


How to debug this situation

Don't automatically assume it is an async issue. First try some simple console.log steps:

const deletePlayer = (id) => {

console.log("Started deletePlayer with id: ",id)   ///////////

 return new Promise(function(resolve, reject) {

  console.log("Inside the promise, id is the same, namely: ",id) ///////////

  pool.query('DELETE FROM Players WHERE player_id = ?' , [id], (error,results) => {
   if (error) {
    reject(error)
   }
   resolve(`Player deleted with ID: ${id}`)
   })
  })
 }

See if 'id' is what you expect it to be

If you don't see any console.log messages printed, maybe, as @steve16351 suggests, you are editing deletePlayer but actually calling another functiondeletePlayers?

In general, avoid using the word "async" for promises used without the "async" keyword

When Promises first arrived in Javascript, they were the practical tool for asynchronous programming, so people sometimes used the term "async" for them in speech.

However since the async keyword arrived, it is better not to use the word "async" for things that are not that keyword.

Simple glossary

Blocking code: a program that simply waits (preventing any other code running) while some external process happens.

Callbacks: the oldest form of asynchronous programming in JS. You tell JS to run a certain function only after some external event has happened.

Promises: a more convenient and readable way to achieve the same effect as callbacks. You can imagine the process to be constructed out of hidden callbacks.

async keyword: an even more convenient and readable way to achieve the same effects as callbacks and promises. It is implicitly made out of promises, although it protects you from having to think about how to construct a new promise.

In response to you reporting that id is 5 inside the promise

This tells us that your original assumption, that the error is due to a variable being undefined, is incorrect. id has the expected value.

Therefore the error is that the API is giving an error in response to this call:

pool.query(
  'DELETE FROM Players WHERE player_id = ?' , 
  [5], 
  (error,results) => {
    if (error) {
      reject(error)
    } else {
    resolve(`Player deleted with ID: ${id}`);
    }
  }
)

So why don't you run exactly that, in simplified form like this:

pool.query(
  'DELETE FROM Players WHERE player_id = ?' , 
  [5], 
  (error,results) => {
    console.log("Error:",JSON.stringify(error,null,2),"Results:",JSON.stringify(error,null,2))
  }
)

This sends an explicit request to pool.query, and explicitly reveals the output. I don't know the format the pool.query API is expecting: perhaps it is not quite right?


推荐阅读