未定义的变量异步 JavaScript

Posted

技术标签:

【中文标题】未定义的变量异步 JavaScript【英文标题】:Undefined variable async JavaScript 【发布时间】:2021-12-21 16:44:10 【问题描述】:

我刚开始学习 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);
 )
)

【问题讨论】:

仅供参考,它是“异步”和“同步”,没有“h”。另外,我在您的代码中没有看到任何async(带有或不带有“h”),那么您是如何收到该错误的? deletePlayers vs deletePlayer的问题吗? 代码看起来有效。您是否多次删除了相同的值? 对不起,deletePlayers/deletePlayer 在代码中很好,我只是为这个问题更改了函数名称,这样更容易阅读! 【参考方案1】:

如何调试这种情况

不要自动假设这是一个异步问题。首先尝试一些简单的 console.log 步骤:

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`)
   )
  )
 

看看 'id' 是不是你所期望的

如果您没有看到打印了任何 console.log 消息,也许正如@steve16351 所暗示的,您正在编辑deletePlayer,但实际上调用了另一个函数deletePlayers

一般来说,避免在没有“async”关键字的情况下使用“async”一词

当 Promise 首次出现在 javascript 中时,它们是异步编程的实用工具,因此人们有时在演讲中使用“异步”一词。

但是自从async 关键字出现后,最好不要将“异步”一词用于不是该关键字的内容。

简单词汇表

阻塞代码:一个程序在某些外部进程发生时简单地等待(阻止任何其他代码运行)。

回调:JS 中最古老的异步编程形式。你告诉 JS 只有在某些外部事件发生后才运行某个函数。

Promises:一种更方便、更易读的方式来实现与回调相同的效果。你可以想象这个过程是由隐藏的回调构造出来的。

async关键字:一种更方便和可读的方式来实现与回调和承诺相同的效果。它隐含地由 Promise 构成,尽管它使您不必考虑如何构建新的 Promise。

响应您报告承诺中的 id 为 5

这告诉我们,您最初的假设是错误是由于未定义的变量造成的,这是不正确的。 id 具有预期值。

因此错误是 API 在响应此调用时给出错误:

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

那你为什么不直接运行,简化形式如下:

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))
  
)

这会向pool.query 发送显式请求,并显式显示输出。我不知道pool.query API 期望的格式:可能不太正确?

【讨论】:

嗨!谢谢你回答这个问题。问题不在于 deletePlayer/deletePlayers,我很快更改了这个问题的函数名称,以便于阅读。我做了这些console.logs,答案总是正确的。运行您的代码给了我:“在承诺中,id 是相同的,即:5”但我收到错误代码:42601

以上是关于未定义的变量异步 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

异步/等待,XHR 请求后返回的变量未定义

如果在模板中使用变量获取错误未定义,则异步 vuex 获取操作状态已填充

执行异步forEach循环后重新定义全局变量[重复]

VueJS:仅在计算内部未定义变量

是否可以 module.exports 从异步函数中导出局部变量?

为啥我的变量在函数内部修改后没有改变? - 异步代码参考