如何使用承诺将语句链接在一起
how to chain statements together using promises
我是节点的新手,正在学习所有关于承诺的知识,特别是 pg-promise。这就是我想用 Express 和 pg-promise:
做的
- 检查电子邮件,
- 如果找不到请检查用户名,
- 如果找不到,请创建一个新用户。
- return 用户 ID
我已经设置了我的回购协议 (db.users),它 sql 运行良好。
在我的授权处理程序中,我不确定如何让 repo 调用一个接一个。语法对我来说似乎很笨拙。这是我目前拥有的:
exports.signup = function( req, res, next ) {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
// See if a user with the given email exists
db.users.byEmail({email: email})
.then(user => {
if (user) {
return res.status(422).send({ error: 'Email is in use'});
} else {
return null; <-- must I return something here?
}
})
.then(() => {
db.users.getUsername({username: username})
.then(user => {
if (user) {
return res.status(422).send({ error: 'Email is in use'});
} else {
return null; <-- must I return something here?
}
...etc
})
也许 pg-promise 不会像这样链接在一起?它们应该相互嵌套还是完全独立的块?另外,不太确定问题在哪里。我已经按照各种教程尝试了所有我能想到的方法,但我收到诸如“无法设置已经设置的 headers”和“未 returned 承诺”之类的错误。如果哪位好心人能指点一下,感激不尽
检查username
和email
的存在是相互独立的。我认为 Promise.all()
比顺序链接承诺更适合您的需要。
exports.signup = function (req, res, next) {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
Promise.all([
db.users.byEmail({
email: email
}),
db.users.getUsername({
username: username
})
]).then((results)=> {
if (results[0] || results[1]) {
return res.status(422).send({
error: 'Email is in use' // same error msg as per your snippet
});
}
// here, code for creating a new user
});
};
执行多个查询时必须使用task
,这样它们才能共享一个连接,否则连接管理会出现性能问题。
db.task(t => {
return t.users.byEmail({email})
.then(user => {
return user || t.users.getUsername({username});
});
})
.then(user => {
if (user) {
res.status(422).send({error: 'Email is in use'});
} else {
// do something else
}
})
.catch(error => {
// process the error
});
假设您的存储库设置如 pg-promise-demo 中所示,它将运行良好。
前 2 个答案是非常糟糕的建议,完全反对 pg-promise says you should do. See Tasks versus root/direct queries。
并且在进行多项更改时,您通常会使用事务 - 使用 tx
而不是 task
。
在 vitaly-t 的指导下,我修改了他的答案,根据失败的内容包含单独的错误消息。我还将下一个 "then" 上移到事务块中,以便在创建用户的下一步中使用事务的 "t"。非常感谢 vitaly-t!
db.task(t => {
return t.users.byEmail({email})
.then(user => {
if (user) {
throw new Error('Email is in use');
} else {
return t.users.byUsername({username});
}
})
.then((user) => {
if (user) {
throw new Error('Username is taken');
} else {
return t.users.addNew({username, email, password});
}
})
})
.then(user => {
res.json({token: tokenForUser(user), username: user.username, aCheck: user.is_admin});
})
.catch(error => {
res.status(422).json({ 'error': error.message});
});
我是节点的新手,正在学习所有关于承诺的知识,特别是 pg-promise。这就是我想用 Express 和 pg-promise:
做的- 检查电子邮件,
- 如果找不到请检查用户名,
- 如果找不到,请创建一个新用户。
- return 用户 ID
我已经设置了我的回购协议 (db.users),它 sql 运行良好。
在我的授权处理程序中,我不确定如何让 repo 调用一个接一个。语法对我来说似乎很笨拙。这是我目前拥有的:
exports.signup = function( req, res, next ) {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
// See if a user with the given email exists
db.users.byEmail({email: email})
.then(user => {
if (user) {
return res.status(422).send({ error: 'Email is in use'});
} else {
return null; <-- must I return something here?
}
})
.then(() => {
db.users.getUsername({username: username})
.then(user => {
if (user) {
return res.status(422).send({ error: 'Email is in use'});
} else {
return null; <-- must I return something here?
}
...etc
})
也许 pg-promise 不会像这样链接在一起?它们应该相互嵌套还是完全独立的块?另外,不太确定问题在哪里。我已经按照各种教程尝试了所有我能想到的方法,但我收到诸如“无法设置已经设置的 headers”和“未 returned 承诺”之类的错误。如果哪位好心人能指点一下,感激不尽
检查username
和email
的存在是相互独立的。我认为 Promise.all()
比顺序链接承诺更适合您的需要。
exports.signup = function (req, res, next) {
const username = req.body.username;
const email = req.body.email;
const password = req.body.password;
Promise.all([
db.users.byEmail({
email: email
}),
db.users.getUsername({
username: username
})
]).then((results)=> {
if (results[0] || results[1]) {
return res.status(422).send({
error: 'Email is in use' // same error msg as per your snippet
});
}
// here, code for creating a new user
});
};
执行多个查询时必须使用task
,这样它们才能共享一个连接,否则连接管理会出现性能问题。
db.task(t => {
return t.users.byEmail({email})
.then(user => {
return user || t.users.getUsername({username});
});
})
.then(user => {
if (user) {
res.status(422).send({error: 'Email is in use'});
} else {
// do something else
}
})
.catch(error => {
// process the error
});
假设您的存储库设置如 pg-promise-demo 中所示,它将运行良好。
前 2 个答案是非常糟糕的建议,完全反对 pg-promise says you should do. See Tasks versus root/direct queries。
并且在进行多项更改时,您通常会使用事务 - 使用 tx
而不是 task
。
在 vitaly-t 的指导下,我修改了他的答案,根据失败的内容包含单独的错误消息。我还将下一个 "then" 上移到事务块中,以便在创建用户的下一步中使用事务的 "t"。非常感谢 vitaly-t!
db.task(t => {
return t.users.byEmail({email})
.then(user => {
if (user) {
throw new Error('Email is in use');
} else {
return t.users.byUsername({username});
}
})
.then((user) => {
if (user) {
throw new Error('Username is taken');
} else {
return t.users.addNew({username, email, password});
}
})
})
.then(user => {
res.json({token: tokenForUser(user), username: user.username, aCheck: user.is_admin});
})
.catch(error => {
res.status(422).json({ 'error': error.message});
});