Javascript 使用bluebird在顺序流中管理异步操作
首先,我不想否认我对承诺非常陌生,并且试图在我的新Node.js应用程序中更好地管理承诺。我使用蓝鸟是基于我从朋友和社区听到的。下面是一个场景: 该应用程序有一个注册流,这是一个典型的用例,在该用例中,必须发生以下事件才能注册新用户:Javascript 使用bluebird在顺序流中管理异步操作,javascript,promise,bluebird,Javascript,Promise,Bluebird,首先,我不想否认我对承诺非常陌生,并且试图在我的新Node.js应用程序中更好地管理承诺。我使用蓝鸟是基于我从朋友和社区听到的。下面是一个场景: 该应用程序有一个注册流,这是一个典型的用例,在该用例中,必须发生以下事件才能注册新用户: 检查用户是否已经存在 如果没有,请添加新用户 发送验证电子邮件 我有3个单独的函数来处理上述每个步骤 下面是我使用Promissions flow提出的建议……但不知何故,我不相信下面的代码: user.isExistingUser(email)
user.isExistingUser(email)
.then((successData) => {
if(successData && successData.length === 0) {
user.signUp(signUpInfo)
.then((successData) => {
emailService.sendVerificationEmail(recipientInfo)
.then((successData) => {
res.json(responseUtility.getApiResponse(successData));
})
.catch((errorObj) => {
res.json(responseUtility.getApiResponse(null, null, errorObj));
});
})
.catch((errorObj) => {
res.json(responseUtility.getApiResponse(null, null, errorObj));
});
} else {
res.json(responseUtility.getApiResponse(null, [{
param: 'email',
msg: 'An account already exists with this email'
}], null));
}
})
.catch((errorObj) => {
res.json(responseUtility.getApiResponse(null, null, errorObj));
});
正如您可能看到的,代码似乎有点太长,可能会变得有点难以跟踪。这里的一些蓝鸟专家能提供更好或更可读的代码吗?你应该更好地利用链接。始终
return
从异步执行操作的函数中获得承诺
user.isExistingUser(email).then(successData => {
if (successData && successData.length === 0) {
return user.signUp(signUpInfo).then(() => {
// ^^^^^^
return emailService.sendVerificationEmail(recipientInfo);
// ^^^^^^
}).then(successData => {
res.json(responseUtility.getApiResponse(successData));
});
} else {
res.json(responseUtility.getApiResponse(null, [{
param: 'email',
msg: 'An account already exists with this email'
}], null));
}
}).catch(errorObj => {
res.json(responseUtility.getApiResponse(null, null, errorObj));
});
你应该更好地利用链接。始终
return
从异步执行操作的函数中获得承诺
user.isExistingUser(email).then(successData => {
if (successData && successData.length === 0) {
return user.signUp(signUpInfo).then(() => {
// ^^^^^^
return emailService.sendVerificationEmail(recipientInfo);
// ^^^^^^
}).then(successData => {
res.json(responseUtility.getApiResponse(successData));
});
} else {
res.json(responseUtility.getApiResponse(null, [{
param: 'email',
msg: 'An account already exists with this email'
}], null));
}
}).catch(errorObj => {
res.json(responseUtility.getApiResponse(null, null, errorObj));
});
我想实现相同代码的一种合理方法可能是:
user.isExistingUser(email)
.then(successData => successData &&
successData.length === 0 ? user.signUp(signUpInfo)
.then(successData => emailService.sendVerificationEmail(recipientInfo))
.then(successData => res.json(responseUtility.getApiResponse(successData)))
: res.json(responseUtility.getApiResponse(null, [{param: 'email', msg: 'An account already exists with this email'}], null)))
.catch(err => res.json(responseUtility.getApiResponse(null, null, err)));
我想实现相同代码的一种合理方法可能是:
user.isExistingUser(email)
.then(successData => successData &&
successData.length === 0 ? user.signUp(signUpInfo)
.then(successData => emailService.sendVerificationEmail(recipientInfo))
.then(successData => res.json(responseUtility.getApiResponse(successData)))
: res.json(responseUtility.getApiResponse(null, [{param: 'email', msg: 'An account already exists with this email'}], null)))
.catch(err => res.json(responseUtility.getApiResponse(null, null, err)));
不理解您的代码有什么问题 基本上,您的代码是嵌套回调。典型的嵌套回调如下所示:
funcation(args..,
function(args...,
function(args){...}
){...}
){...}
你的答案是:
function(args).then(()=> {
function(args).then(() => {
function(args){...}
})
})
差别不大,不是吗
这是使用承诺的正确方式。 解决你的问题的关键是兑现承诺。这实际上是承诺的全部要点 基本上,您希望您的
然后回调返回一个承诺。通过这种方式,您可以链接您的承诺,以避免代码的嵌套回调样式
每个。然后方法本身总是返回一个承诺
promiseB = promiseA.then(()=> {
// callback
return promiseC
});
如果callback
返回像上面这样的承诺,您可以有效地想到promiseB=promiseC
。现在,如果我们有
promiseC = promiseA.then(()=> {
// callback
return promiseB
});
promiseE = promiseC.then(()=> {
// callback
return promiseD
});
您可以将它们链接在一起。然后,可以将上述内容缩短为:
promiseA.then(()=> {
// callback
return promiseB
}).then(()=> {
// callback
return promiseD
});
直接回答您的问题。
让userPromise=user.isExistingUser(电子邮件);
//处理新用户
用户承诺
.然后((用户数据)=>{
断言userData.length==0;
//报名
//假设user.signUp是一个承诺,recipientInfo是其解析值
返回user.signUp(userData.signUpInfo);
})
.然后((recipientInfo)=>{
//发送验证电子邮件
//假设user.sentVerificationEmail是一个承诺,其解析值为emailSuccessData
返回user.sentVerificationEmail(recipientInfo)
})
。然后((emailSuccessData)=>{
res.json(responseutability.getApiResponse(emailSuccessData));
})
//如果先前的任何承诺被拒绝,
//接下来的。然后将被有效地绕过并落在这个陷阱中
.catch((错误)=>{
res.json(responseutability.getApiResponse(null,null,err));
})
//处理现有用户
userPromise.then((successData)=>{
assert successData.length>0
常量json=[{
参数:“电子邮件”,
msg:'此电子邮件已存在一个帐户'
}]
res.json(responseutability.getApiResponse(null,json,null));
});
//不用再抓了。如果userPromise被拒绝,它将由上面的catch处理。
不理解您的代码有什么问题。
基本上,您的代码是嵌套回调。典型的嵌套回调如下所示:
funcation(args..,
function(args...,
function(args){...}
){...}
){...}
你的答案是:
function(args).then(()=> {
function(args).then(() => {
function(args){...}
})
})
差别不大,不是吗
这是使用承诺的正确方式。
解决你的问题的关键是兑现承诺。这实际上是承诺的全部要点
基本上,您希望您的然后回调返回一个承诺。通过这种方式,您可以链接您的承诺,以避免代码的嵌套回调样式
每个。然后方法本身总是返回一个承诺
promiseB = promiseA.then(()=> {
// callback
return promiseC
});
如果callback
返回像上面这样的承诺,您可以有效地想到promiseB=promiseC
。现在,如果我们有
promiseC = promiseA.then(()=> {
// callback
return promiseB
});
promiseE = promiseC.then(()=> {
// callback
return promiseD
});
您可以将它们链接在一起。然后,可以将上述内容缩短为:
promiseA.then(()=> {
// callback
return promiseB
}).then(()=> {
// callback
return promiseD
});
直接回答您的问题。
让userPromise=user.isExistingUser(电子邮件);
//处理新用户
用户承诺
.然后((用户数据)=>{
断言userData.length==0;
//报名
//假设user.signUp是一个承诺,recipientInfo是其解析值
返回user.signUp(userData.signUpInfo);
})
.然后((recipientInfo)=>{
//发送验证电子邮件
//假设user.sentVerificationEmail是一个承诺,其解析值为emailSuccessData
返回user.sentVerificationEmail(recipientInfo)
})
。然后((emailSuccessData)=>{
res.json(responseutability.getApiResponse(emailSuccessData));
})
//如果先前的任何承诺被拒绝,
//接下来的。然后将被有效地绕过并落在这个陷阱中
.catch((错误)=>{
res.json(responseutability.getApiResponse(null,null,err));
})
//处理现有用户
userPromise.then((successData)=>{
assert successData.length>0
常量json=[{
参数:“电子邮件”,
msg:'此电子邮件已存在一个帐户'
}]
res.json(responseutability.getApiResponse(null,json,null));
});
//不用再抓了。如果userPromise被拒绝,它将由上面的catch处理。
doeshelp@JaromandaX感谢您的快速回复…我想知道如果电子邮件验证步骤失败会发生什么…是否可以捕获任何错误。最后捕获块?另外,我想知道我是否可以在bluebird中使用.mapseries api?是的,单个catchblock可以捕获任何拒绝-我不知道bluebird promise sugar,我只使用本机承诺—尽管Bluebird具有明显的性能优势—但我不确定在这种情况下为什么要使用它,因为您需要从.then()
处理程序中返回所有嵌套承诺