.then 语句不按顺序执行
.then statements not executing sequentially
我有一个使用 Node.js/Express 的应用程序。在此代码中,我有以下承诺,旨在检查我的 (PostGres) 数据库中是否已存在电子邮件:
//queries.js
const checkEmail = function(mail) {
return new Promise(function(resolve, reject) {
pool.query('SELECT * FROM clients WHERE email = ', [mail], function(error, results) {
if (error) {
reject(new Error('Client email NOT LOCATED in database!'));
} else {
resolve(results.rows[0]);
}
}) //pool.query
}); //new promise
}
在我的 'main (server.js)' 脚本文件中,我有一个在提交 'signup' 表单时调用的路由。当处理此路由的 post 时...我 运行 上面的脚本检查传递的电子邮件地址是否已经位于数据库中,以及其他各种 'hashing' 例程:
我的代码如下:
//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”语句和承诺出于某种原因有些令人困惑。我先谢谢你了。
TLDR - 您必须将 函数引用 传递给 .then()
,以便 promise 基础结构稍后可以调用该函数。您在代码中的多个地方都没有这样做。
您的代码中的一个更具体的示例:
你有几个这样的结构:
.then(db.createUser().then())
这是不正确的。这告诉解释器 运行 db.createUser()
立即 并将其 return 结果(承诺)传递给.then()
。 .then()
将完全忽略你传递的任何不是函数引用的内容,你的承诺将不会被正确链接。
相反,您必须将函数引用传递给 .then()
,就像这样(不确定您真正想要的执行逻辑):
.then(() => { return db.createUser.then()})
那么这里的要点是,如果你要对异步操作进行排序,那么你必须链接它们的承诺,这意味着你不能执行第二个,直到第一个调用你传递给 .then()
的函数。您没有将函数传递给 .then()
,而是立即执行一个函数,然后将承诺传递给 .then(p)
,.then()
完全忽略了该承诺,并且您的函数在父承诺之前执行已解决。
仅供参考,对一堆异步操作进行排序(看起来您正在尝试在此处执行)可以利用 await
而不是 .then()
并最终得到看起来更简单的代码。
我有一个使用 Node.js/Express 的应用程序。在此代码中,我有以下承诺,旨在检查我的 (PostGres) 数据库中是否已存在电子邮件:
//queries.js
const checkEmail = function(mail) {
return new Promise(function(resolve, reject) {
pool.query('SELECT * FROM clients WHERE email = ', [mail], function(error, results) {
if (error) {
reject(new Error('Client email NOT LOCATED in database!'));
} else {
resolve(results.rows[0]);
}
}) //pool.query
}); //new promise
}
在我的 'main (server.js)' 脚本文件中,我有一个在提交 'signup' 表单时调用的路由。当处理此路由的 post 时...我 运行 上面的脚本检查传递的电子邮件地址是否已经位于数据库中,以及其他各种 'hashing' 例程:
我的代码如下:
//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”语句和承诺出于某种原因有些令人困惑。我先谢谢你了。
TLDR - 您必须将 函数引用 传递给 .then()
,以便 promise 基础结构稍后可以调用该函数。您在代码中的多个地方都没有这样做。
您的代码中的一个更具体的示例:
你有几个这样的结构:
.then(db.createUser().then())
这是不正确的。这告诉解释器 运行 db.createUser()
立即 并将其 return 结果(承诺)传递给.then()
。 .then()
将完全忽略你传递的任何不是函数引用的内容,你的承诺将不会被正确链接。
相反,您必须将函数引用传递给 .then()
,就像这样(不确定您真正想要的执行逻辑):
.then(() => { return db.createUser.then()})
那么这里的要点是,如果你要对异步操作进行排序,那么你必须链接它们的承诺,这意味着你不能执行第二个,直到第一个调用你传递给 .then()
的函数。您没有将函数传递给 .then()
,而是立即执行一个函数,然后将承诺传递给 .then(p)
,.then()
完全忽略了该承诺,并且您的函数在父承诺之前执行已解决。
仅供参考,对一堆异步操作进行排序(看起来您正在尝试在此处执行)可以利用 await
而不是 .then()
并最终得到看起来更简单的代码。