JavaScript中的两个异步函数(Node.js)
我有一个异步的数据库查询(函数),因此我需要使用回调函数(这没问题)。但是,在Node.js中,我需要在同一个POST函数中进行两个单独的查询。两者都是异步的,所以我在如何继续执行POST方面遇到了麻烦 目标:JavaScript中的两个异步函数(Node.js),javascript,node.js,postgresql,asynchronous,Javascript,Node.js,Postgresql,Asynchronous,我有一个异步的数据库查询(函数),因此我需要使用回调函数(这没问题)。但是,在Node.js中,我需要在同一个POST函数中进行两个单独的查询。两者都是异步的,所以我在如何继续执行POST方面遇到了麻烦 目标: 验证表格条目是否存在畸形等 保存前检查数据库中是否存在用户名(必须唯一) 保存前检查数据库中是否存在电子邮件(必须唯一) 如果一切正常,请保存用户,否则会抛出一些错误 通常情况下,我会有这样的想法(过于简单化): 它只有一个异步查询,所以只有一个回调。通常我只会得到数据库结果并呈现一个页
postUser = function(req, res, next) {
// Some static form validation (works, no issues)
var usernameExistsCallback = function(err, exists) {
// Does the username exist? True/false
}
// DB query - passes true or false to the callback
usernameExists(username, usernameExistsCallback);
var emailExistsCallback = function(err, exists) {
// Does the email exist? True/false
}
// DB query - passes true or false to the callback
emailExists(email, emailExistsCallback);
// Check if ALL validation constraints check out, implement error logic
}
postUser = function(req, res, next) {
var emailExistsCallback = function(err, exists) {
// Does the email exist? True/false
// Check if ALL validation constraints check out, implement error logic
next(); // <= you should finally call "next" callback in order to proceed
}
var usernameExistsCallback = function(err, exists) {
// Does the username exist? True/false
emailExists(email, emailExistsCallback); // <= note this
}
usernameExists(username, usernameExistsCallback);
}
模块是异步的,因此查询需要回调(如果我想返回任何值,否则我可以运行查询并断开连接)。我在执行这两个查询时没有问题。我可以console.log()
在回调中找到正确的结果。但是现在我不知道以后如何在我的postaser
函数中访问这些结果
我已经阅读了所有关于异步JavaScript函数的书籍,但是我已经在这本书上苦思冥想了三个小时,现在我尝试了一些可笑的事情(比如设置全局变量[oh my!]),但都没有用
我需要这两个查询的结果是
true
或false
。如何组织此代码以便能够在postaser
功能中使用这些结果?在我看来,我需要第三次回调之类的东西,但我不知道如何实现这样的东西。我有必要开始使用吗?这是个好主意吗?到目前为止,这个应用程序中没有什么是超级复杂的,我希望保持低依赖性—这是有意义的。您可以使用一个公共变量来跟踪您得到了多少响应。如果两者都有,那么就可以在第三个“回调”中执行需要它们的操作,我称之为done():
您可能应该根据应用程序的需要添加错误处理,特别是在两个SQL回调中,但这是一个很好的并行IO ajax模式,可以满足您的需要。这是什么:
postUser = function(req, res, next) {
// Some static form validation (works, no issues)
var emailExistsCallback = function(err, exists) {
// Does the email exist? True/false
var usernameExistsCallback = function(err, exists) {
// Does the username exist? True/false
// DO STUFF HERE
}
// DB query - passes true or false to the callback
usernameExists(username, usernameExistsCallback);
}
// DB query - passes true or false to the callback
emailExists(email, emailExistsCallback);
// Check if ALL validation constraints check out, implement error logic
}
最简单的方法是嵌套如下函数:
postUser = function(req, res, next) {
// Some static form validation (works, no issues)
var usernameExistsCallback = function(err, exists) {
// Does the username exist? True/false
}
// DB query - passes true or false to the callback
usernameExists(username, usernameExistsCallback);
var emailExistsCallback = function(err, exists) {
// Does the email exist? True/false
}
// DB query - passes true or false to the callback
emailExists(email, emailExistsCallback);
// Check if ALL validation constraints check out, implement error logic
}
postUser = function(req, res, next) {
var emailExistsCallback = function(err, exists) {
// Does the email exist? True/false
// Check if ALL validation constraints check out, implement error logic
next(); // <= you should finally call "next" callback in order to proceed
}
var usernameExistsCallback = function(err, exists) {
// Does the username exist? True/false
emailExists(email, emailExistsCallback); // <= note this
}
usernameExists(username, usernameExistsCallback);
}
positioner=功能(请求、恢复、下一步){
var emailExistsCallback=函数(错误,存在){
//电子邮件是否存在?对/错
//检查是否所有验证约束都已签出,实现错误逻辑
next();//我曾考虑过这样做,但我认为这会让人感到非常困惑……我需要进行一些错误处理,这样太过嵌套是很困难的(imo)。我将尝试这两种解决方案,看看什么看起来/感觉最好:)您也可以使用承诺。我在node中没有编写太多程序,但我刚刚用python/txpostgres完成了一个项目,这是异步调用。我有一些查询,在知道结果之前必须连续运行8次。对于那些我使用延迟的查询,我不知道您在node中是否有这些查询?我相信承诺和异议是Node中的一件事。我记得最近读到过关于它们的文章,尽管我没有特别看到它们有什么用处。在当前的规范中,项目中没有任何东西会变得足够复杂,需要查询这些技术。最复杂的事情是运行这两个查询大多数帖子只运行一个帖子,结果是直接的和即时的,所以现在还不需要这些东西:PI很快就会测试出来!我要参加一个会议,所以我会让你知道这是怎么回事。不过看起来很有希望:)快速问一个问题——有了这种逻辑,我会构建错误吗在回调中,并将它们传递给done()
?或者我会假设在调用done()
时,这两个字段已被验证(因为否则我会在原始回调中已经呈现一些错误)?在任何情况下,我很快就会玩它,看看它能起什么作用。这种模式的优点是两个SQL请求同时执行,并避免嵌套。您可以通过两种方式来处理错误:在“旧”回调中单独处理错误,或通过将错误转发给ala done(错误响应),并在那里处理所有内容。如果您已经有了错误处理,则可能最容易将其保留。如果您需要添加错误处理,我会将所有内容传递给done(),可能会使done的参数像许多节点一样:callbacks done(err,resp)。我认为将参数传递给done())
最有意义。对我来说,done()
意味着完成了所有验证步骤,是时候呈现带有结果的页面了:成功还是失败!结果取决于验证是否签出。我认为这种方法更有意义,特别是因为我可以在done()中创建所有错误的列表
并根据该列表正确呈现页面。我很快会查看一个真正的实现,但现在我必须签署一份租约。我会让你知道这个策略是如何运作的:)当我几天前说测试它的时候……我想我有点夸张了!好吧,我已经摆弄了你的想法,它非常有效。我不得不说,这是非常聪明的!我想我可能会经常使用这种模式:)最酷的部分是,我可以在数据库回调中使用req.flash(param,message)
,而不是将错误传递给处理程序函数,这些可以稍后在done()中访问
。对于需要数据库查找的表单验证,这似乎是一种非常简洁的错误处理方法。非常非常好,谢谢!我考虑过使用异步,因为我可能可以通过单个回调并行运行它们(对此不确定,不太了解abo)