- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在检索突变结果时遇到了挑战。我需要创建一个数据库记录并发送一封电子邮件通知用户注册成功。因为电子邮件的发送和数据库更新都是服务器端的,所以我想在同一个突变中同时进行。如果电子邮件消息失败,则不得更新数据库。所以我有以下突变:
Mutation: {
createDealer(_, params) {
console.log("params: " + JSON.stringify(params));
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(params.dealer.password, salt, function(err, hash) {
// Store hash in your password DB.
console.log("hashed password " + params.dealer.password)
params.dealer.password = hash;
console.log("hashed password " + params.dealer.password + " Hash: " + hash);
let session = driver.session();
let query = "CREATE (d:Dealer {email:$dealer.email}) SET d += $dealer RETURN d";
let here = "here".link("mymail@example.com");
let messageObj = {
to: params.dealer.email,
subject: 'Dealer Registration',
text: `Thank you for signing up. To complete and activate your registration please click ${here}.`
}
return (sendEmail(messageObj))
.then(data => {
console.log('SendMail data....' + JSON.stringify(data));
return session.run(query, params)
})
.then(result => {
console.log('SendNeo4j data....' + JSON.stringify(result));
return result.records[0].get("d").properties
})
.catch((err) => {
console.log(err);
});
//});
});
}); // genSalt
} // Create Dealer
}, // Mutation
即使认为这两个操作都成功了,我似乎也无法检索到结果。我得到“未定义”的原因是: console.log('SendMail 数据....' + JSON.stringify(data));尽管 console.log('SendNeo4j 数据....' + JSON.stringify(result));确实显示正确的数据
但是 graphiql 为 mutate 返回“null”。这是 graphiql 突变:
mutation CreateDealer($dealer: DealerInput!) {
createDealer(dealer: $dealer) {
email
name
}
}
当然是使用 DealerInput 变量。
我已经阅读过在哪里可以从查询/变更中检索多个结果,但我不确定它是如何工作的。在这里,我需要 sendEmail 的结果和我的 Angular/apollo 前端的数据库更新....我想成像 graphiql 对 sendEmail 一无所知,但我希望它返回我请求的属性。
发送邮件:
module.exports = (message) =>
new Promise((resolve, reject) => {
const data = {
from: 'mymail@example.com',
to: message.to,
subject: message.subject,
text: message.text
};
mailgun.messages().send(data, (error) => {
if (error) {
return reject(error);
}
return resolve();
});
});
有比我经验多一点的人可以帮助我吗...谢谢
最佳答案
这里有几件事要解决。在回调中返回一个 Promise(或任何其他值)不会做任何事情,这样做不会让你像你想要的那样链接额外的 Promise。相反,您的 promise 会在回调中被触发并且不会被等待。
根据一般经验,不要混合使用 Promises 和回调。如果您绝对必须使用回调,请始终将回调包装在 Promise 中(就像您在 sendMail 中所做的那样)。幸运的是,当今大多数流行的库都支持回调和 Promises。以下是重构上述代码以正确链接所有 Promise 的方法:
createDealer(_, params) {
return bcrypt.hash(params.dealer.password, 10) // note the return here!
.then(hash => {
params.dealer.password = hash
const session = driver.session()
const query = "CREATE (d:Dealer {email:$dealer.email}) SET d += $dealer RETURN d"
const here = "here".link("mymail@example.com")
const messageObj = {
to: params.dealer.email,
subject: 'Dealer Registration',
text: `Thank you for signing up. To complete and activate your registration please click ${here}.`
}
return sendEmail(messageObj) // note the return here!
}).then(data => {
return session.run(query, params) // note the return here!
}).then(result => {
result.records[0].get("d").properties // note the return here!
})
bcrypt.hash
如果您不传入盐,它会自动为您生成盐——无需调用两个单独的函数bcrypt.hash
开始我们的 Promise 链,所以我们需要返回它返回的 Promise。解析器必须返回一个值或将解析为一个值的 Promise,否则返回 null。then
中,我们返回一个 Promise。通过这种方式,我们“链接”了我们的 Promise,允许我们在解析器中返回的最终值成为链中最后一个 Promise 解析的值。我们还需要修复您的 sendMail
函数以实际返回值。您在函数内部正确地返回了新的 Promise,但您还需要传递返回的 data
对象来解析。这告诉 Promise 解决该值。
module.exports = (message) => new Promise((resolve, reject) => {
const data = // ...etc
mailgun.messages().send(data, (error) => {
if (error) reject(error) // no need to return, it's pointless
resolve(data) // pass data to resolve
})
})
旁注:看起来像 official mailgun library支持 promise 。
此外,我强烈建议您考虑使用 async/await,尤其是在处理长 Promise 链时。它不易出错且可读性更强:
createDealer async (_, params) {
const hash = await bcrypt.hash(params.dealer.password)
params.dealer.password = hash
const session = driver.session()
const query = "CREATE (d:Dealer {email:$dealer.email}) SET d += $dealer RETURN d"
const here = "here".link("mymail@example.com")
const messageObj = {
to: params.dealer.email,
subject: 'Dealer Registration',
text: `Thank you for signing up. To complete and activate your registration please click ${here}.`
}
const emailResult = await sendEmail(messageObj)
const result = await session.run(query, params)
return result.records[0].get("d").properties // still need to return!
}
编辑:关于捕获错误,GraphQL 将捕获解析器抛出的任何错误,这意味着您通常可以自己跳过使用catch
。例如,如果您的 mailgun 请求失败,它将生成某种错误,并且您的查询将为 data
和 errors
数组中的错误详细信息返回 null。
这可能就足够了,尽管 1) 您可能想在别处记录您的错误堆栈; 2) 在生产中,您可能不想向公众公开内部错误详细信息。
这意味着您可能想要使用自定义错误。作为奖励,您可以为您的错误添加一些自定义属性,以帮助客户有效地处理它们。所以你的代码最终可能看起来更像这样:
class DeliveryFailureError extends Error {}
DeliveryFailureError.code = 'DELIVERY_FAILURE'
DeliveryFailureError.message = 'Sorry, we could not deliver the email to your account'
try {
await mailgun.messages.create()
} catch (err) {
logger.error('Mailgun request failed:', err.stack)
throw new DeliveryFailureError()
}
关于javascript - 我的 graphql 服务器突变返回空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50223649/
我的问题:非常具体。我正在尝试想出解析以下文本的最简单方法: ^^domain=domain_value^^version=version_value^^account_type=account_ty
好吧,这就是我的困境: 我正在为 Reddit 子版 block 开发常见问题解答机器人。我在 bool 逻辑方面遇到了麻烦,需要一双更有经验的眼睛(这是我在 Python 中的第一次冒险)。现在,该
它首先遍历所有 y 值,然后遍历所有 x 值。我需要 X 和 y 同时改变。 For x = 3 To lr + 1 For y = 2 To lr anyl.Cells(x, 1)
假设我有一个包含 2 列的 Excel 表格:单元格 A1 到 A10 中的日期和 B1 到 B10 中的值。 我想对五月日期的所有值求和。我有3种可能性: {=SUM((MONTH(A1:A10)=
如何转换 Z-score来自 Z-distribution (standard normal distribution, Gaussian distribution)到 p-value ?我还没有找到
我正在重写一些 Javascript 代码以在 Excel VBA 中工作。由于在这个网站上搜索,我已经设法翻译了几乎所有的 Javascript 代码!但是,有些代码我无法准确理解它在做什么。这是一
我遇到过包含日期格式的时间戳日期的情况。然后我想构建一个图表,显示“点击”项目的数量“每天”, //array declaration $array1 = array("Date" => 0); $a
我是scala的新手! 我的问题是,是否有包含成员的案例类 myItem:Option[String] 当我构造类时,我需要将字符串内容包装在: Option("some string") 要么 So
我正在用 PHP 创建一个登录系统。我需要用户使用他或她的用户名或电子邮件或电话号码登录然后使用密码。因为我知道在 Java 中我们会像 email==user^ username == user 这
我在 C++ 项目上使用 sqlite,但是当我在具有文本值的列上使用 WHERE 时出现问题 我创建了一个 sqlite 数据库: CREATE TABLE User( id INTEGER
当构造函数是显式时,它不用于隐式转换。在给定的代码片段中,构造函数被标记为 explicit。那为什么在 foo obj1(10.25); 情况下它可以工作,而在 foo obj2=10.25; 情况
我知道这是一个主观问题,所以如果需要关闭它,我深表歉意,但我觉得它经常出现,让我想知道是否普遍偏爱一种形式而不是另一种形式。 显然,最好的答案是“重构代码,这样你就不需要测试是否存在错误”,但有时没有
这两个 jQuery 选择器有什么区别? 以下是来自 w3schools.com 的定义: [attribute~=value] 选择器选择带有特定属性,其值包含特定字符串。 [attribute*=
为什么我们需要CSS [attribute|=value] Selector根本当 CSS3 [attribute*=value] Selector基本上完成相同的事情,浏览器兼容性几乎相似?是否存在
我正在解决 regx 问题。我已经有一个像这样的 regx [0-9]*([.][0-9]{2})。这是 amont 格式验证。现在,通过此验证,我想包括不应提供 0 金额。比如 10 是有效的,但
我正在研究计算机科学 A 考试的样题,但无法弄清楚为什么以下问题的正确答案是正确的。 考虑以下方法。 public static void mystery(List nums) { for (
好的,我正在编写一个 Perl 程序,它有一个我收集的值的哈希值(完全在一个完全独立的程序中)并提供给这个 Perl 脚本。这个散列是 (string,string) 的散列。 我想通过 3 种方式对
我有一个表数据如下,来自不同的表。仅当第三列具有值“债务”并且第一列(日期)具有最大值时,我才想从第四列中获取最大值。最终值基于 MAX(DATE) 而不是 MAX(PRICE)。所以用简单的语言来说
我有一个奇怪的情况,只有错误状态保存到数据库中。当“状态”应该为 true 时,我的查询仍然执行 false。 我有具有此功能的 Controller public function change_a
我有一个交易表(针对所需列进行了简化): id client_id value 1 1 200 2 2 150 3 1
我是一名优秀的程序员,十分优秀!