【问题标题】:.then statements not executing sequentially.then 语句不按顺序执行
【发布时间】:2021-09-15 12:15:04
【问题描述】:

我有一个使用 Node.js/Express 的应用程序。在此代码中,我有以下承诺,旨在检查我的(PostGres)数据库中是否已存在电子邮件:

//queries.js

const checkEmail = function(mail) {

 return new Promise(function(resolve, reject) {

  pool.query('SELECT * FROM clients WHERE email = $1', [mail], function(error, results) {
   if (error) {
   reject(new Error('Client email NOT LOCATED in database!'));     
   } else {
   resolve(results.rows[0]);
   }
  })  //pool.query

 });  //new promise 
}

在我的“主 (server.js)”脚本文件中,我有一个在提交“注册”表单时调用的路由。处理此路由的帖子时...我运行上面的脚本来检查传递的电子邮件地址是否已经位于数据库中,以及各种其他“散列”例程:

我的代码如下:

//server.js

const db = require('./queries');
const traffic = require('./traffic'); 
const shortid = require('shortid');

...

app.post('/_join_up', function(req, res) {

 if (!req.body) {
 console.log('ERROR: req.body has NOT been returned...');
 return res.sendStatus(400)
 }


var newHash, newName;
var client = req.body.client_email;
var creds = req.body.client_pword;
var newToken = shortid.generate();
var firstname = req.body.client_alias; 


 db.sanitation(client, creds, firstname).then(
  function(direction) {
    console.log('USER-SUPPLIED DATA HAS PASSED INSPECTION');
  }
 ).then(
 db.checkEmail(client).then(
  function(foundUser) {
    console.log('HEY THERE IS ALREADY A USER WITH THAT EMAIL!', foundUser);
  }, 
  function(error) {
    console.log('USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...');
  }
 )).then(
 traffic.hashPassword(creds).then(
  function(hashedPassword) {
    console.log('PASSWORD HASHED');
    newHash = hashedPassword;
  }, 
  function(error) {
    console.log('UNABLE TO HASH PASSWORD...' + error);
  }
 )).then(
 traffic.hashUsername(firstname).then(
  function(hashedName) {
    console.log('NAME HASHED');
    newName = hashedName;
  }, 
  function(error) {
    console.log('UNABLE TO HASH NAME...' + error);
  }
 )).then(
 db.createUser(client, newName, newHash, newToken).then(
  function(data) {
  console.log('REGISTERED A NEW CLIENT JOIN...!!!');
    
  res.redirect('/landing');  //route to 'landing' page...
  }, 
  function(error) {
    console.log('UNABLE TO CREATE NEW USER...' + error);
  }
 ))
 .catch(function(error) {
 console.log('THERE WAS AN ERROR IN THE SEQUENTIAL PROCESSING OF THE USER-SUPPLIED INFORMATION...' + error);
 res.redirect('/');  
 });

});  //POST '_join_up' is used to register NEW clients...

我的问题是“.then”语句似乎没有按顺序运行。我的印象是这样的命令只能一个接一个地运行……每个命令只有在前一个命令完成时才运行。这是基于显示“console.log”语句读数的日志:

USER-SUPPLIED DATA HAS PASSED INSPECTION
PASSWORD HASHED
NAME HASHED
UNABLE TO CREATE NEW USER...Error: Unable to create new CLIENT JOIN!
USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...

如前所述,我的印象是 '.then' 语句应该同步运行,因此最后一条语句(“用户电子邮件当前不在数据库中......因此它没问题......”)实际上应该是根据'.then'语句的布局,在第一个之后......在“PASSWORD HASHED”之前。这是正常行为...还是我的代码有错误?

对于我的困惑,我感到抱歉,但我发现 '.then' 陈述和承诺由于某种原因有些令人困惑。提前谢谢你。

【问题讨论】:

    标签: node.js express promise synchronous


    【解决方案1】:

    TLDR - 您必须将 函数引用 传递给 .then(),以便 Promise 基础结构稍后可以调用该函数。您没有在代码中的多个地方这样做。

    您的代码中更具体的示例:

    你有几个这样的结构:

    .then(db.createUser().then())
    

    这是不正确的。这告诉解释器运行db.createUser()立即并将其返回结果(承诺)传递给.then().then() 将完全忽略您传递的任何不是函数引用的内容,并且您的承诺不会被正确链接。

    相反,您必须将函数引用传递给.then(),类似这样(不确定您真正想要什么执行逻辑):

    .then(() => { return db.createUser.then()})
    

    那么这里的重点是,如果你要对异步操作进行排序,那么你必须链接它们的承诺,这意味着你不能执行第二个,直到第一个调用你传递给.then() 的函数。您没有将函数传递给.then(),而是立即执行一个函数,然后将一个promise 传递给.then(p).then() 完全忽略了它,并且您的函数在父promise 解决之前执行。


    仅供参考,对一堆异步操作进行排序(您似乎在这里尝试这样做)可以利用 await 而不是 .then() 并最终得到看起来更简单的代码。

    【讨论】:

    • 感谢您的回复。明天我将尝试重写此代码。事实上,所有“.then”语句的代码都是一团糟。所以基本上,只是为了确认......我应该使用类似于“.then(() => { return db.createUser.then(function(data){}, function(error){}) 的结构重写})“ ...正确的?再次感谢您的回复,非常感谢。
    • @Pangit - 我的建议是使用await 而不是.then() 重写,因为在对多个异步操作进行排序时代码会更简单。但是,如果您要使用 .then(),则必须将函数引用传递给它,如我的示例所示。
    • 再次感谢您的意见。我最终能够将一些看起来有效的代码放在一起。我确实使用了基于“.then”语句的方法。我将这篇文章用作参考“pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html”...该资源上有一些我发现有用的代码。经过几次测试运行后,我的所有“console.log”语句都以正确的顺序执行,与以前不同。再次感谢您...非常感谢您的回复!
    猜你喜欢
    • 2014-03-05
    • 1970-01-01
    • 2011-09-27
    • 2023-04-04
    • 2012-05-28
    • 1970-01-01
    • 2020-08-30
    • 2018-02-18
    • 2014-08-23
    相关资源
    最近更新 更多