JavaScript 函数响应和链式承诺
JavaScript function response and chained promises
我有一个Parse
CloudCode
beforeSave
函数,大致执行以下操作:
- 运行查询以检查要保存的用户是否存在重复的用户;
- 如果没有重复项,我调用
response.success()
,这意味着代码可以继续并允许保存新用户; - 但是,如果有重复项,我想取
existing user
,获取一个group
对象并将existing user
添加到group
中。
为此,我使用链式承诺来使代码更清晰。代码如下:
Parse.Cloud.beforeSave("Contact", function(request, response) {
var facebookID = request.object.get("facebookID");
var email = request.object.get("email");
var queryFb;
if (facebookID) {
queryFb = new Parse.Query(Parse.User);
queryFb.equalTo("facebookID", facebookID);
}
var queryEmail;
if (email) {
queryEmail = new Parse.Query(Parse.User);
queryEmail.equalTo("email", email);
}
var query;
if (facebookID && email) {
query = new Parse.Query.or(queryFb, queryEmail);
} else if (facebookID) {
query = queryFb;
} else {
query = queryEmail;
}
var user;
query.first().then(function(user) {
if (!user) {
response.success();
} else {
var groupQuery = new Parse.Query("Group");
groupQuery.equalTo("title", "ssAll");
groupQuery.equalTo("owner", request.user);
return groupQuery.first();
}
}).then(function(group) {
group.addUnique("contacts", user);
return group.save();
}).then(function(success) {
response.error("NOT ERROR - new object was NOT created");
}, function(error) {
response.error(error);
});
});
在我的测试用例中,查询返回 !user
,因此调用response.success()
消息 - 一切都很好。但是,此响应似乎随后会沿着 promise 链向下传输,该 promise 链适用于查询返回user
对象的情况。因此,我的函数在第 group.addUnique("contacts", user);
行以错误终止,因为显然,group
对象是undefined
。
如何解决此问题?
代码需要一些改进。 关键的改进是为第二个承诺的解决方案(第二个then
块)提供一致的起始条件。 OP 代码在没有现有用户的情况下称为 response.success()。 这很好,除了执行仍然下降到下一个分辨率,在一种情况下,group
参数未定义。
新代码通过返回existingUser
(更新组后)或null
来解决此问题。 Null 告诉下一个承诺解析调用success()
并允许保存继续,否则,阻止保存。
另请注意,第一个块的 user
参数与封闭范围内的var user
冲突是错误的。 我尝试在下面使用变量命名来突出显示代码考虑的两种不同类型的用户......
Parse.Cloud.beforeSave("Contact", function(request, response) {
var facebookID = request.object.get("facebookID");
var email = request.object.get("email");
// moved into a function so we can test and deal with it tersely
findUserByEmailOrFB(email, facebookID).then(function(existingUser) {
return (existingUser)? addContactToGroupOwnedBy(request.user, existingUser) : null;
}).then(function(existingUser) {
if (existingUser) {
response.error("NOT ERROR - new object was NOT created");
} else {
response.success();
}
}, function(error) {
response.error(error);
});
});
// find the group owned by ownerUser, add contactUser to its contacts return a promise fulfilled as contactUser
function addContactToGroupOwnedBy(ownerUser, contactUser) {
var groupQuery = new Parse.Query("Group");
groupQuery.equalTo("title", "ssAll");
groupQuery.equalTo("owner", ownerUser);
return groupQuery.first().then(function(group) {
group.addUnique("contacts", contactUser);
return group.save().then(function() { return contactUser; });
});
}
function findUserByEmailOrFB(email, facebookID) {
var queryFb;
if (facebookID) {
queryFb = new Parse.Query(Parse.User);
queryFb.equalTo("facebookID", facebookID);
}
var queryEmail;
if (email) {
queryEmail = new Parse.Query(Parse.User);
queryEmail.equalTo("email", email);
}
var query;
if (facebookID && email) {
query = new Parse.Query.or(queryFb, queryEmail);
} else if (facebookID) {
query = queryFb;
} else {
query = queryEmail;
}
return query.first();
}
问题是,无论检查用户是否成功(还没有这样的用户),您总是在解析第一个承诺。但是,实际上您永远不必解决承诺。我建议你像这样分离错误情况:
query.first().then(function(user) {
if (!user) {
response.success();
} else {
addUserToGroup(request.user).then(function() {
response.error("NOT ERROR - new object was NOT created");
}, function(error) {
response.error(error);
});
}
});
function addUserToGroup(user) {
var groupQuery = new Parse.Query("Group");
groupQuery.equalTo("title", "ssAll");
groupQuery.equalTo("owner", user);
return groupQuery.first().then(function(group) {
group.addUnique("contacts", user);
return group.save();
});
}
如您所见,第一个承诺不必解决,因为无论如何都不会使用结果。
相关文章:
- 从函数返回角度承诺
- 如何按照承诺使用mocha/chai/chai测试ES7异步函数
- 两个函数之间的角度承诺
- 当链接javascript承诺时,如何处理then()函数中的条件
- 角承诺的“then”函数的成功回调的词汇范围是什么?
- 在承诺函数从 pouchdb 填充数据之前触发 Ionic/Angular $watch的问题
- 将 VAR 值置于承诺函数之外
- 函数抽象和承诺函数作为参数
- 如何递归调用承诺函数
- 如何将参数传递给承诺函数
- 在这种情况下,我将如何使用 javascript 创建一个承诺函数
- nodejs Q.all承诺函数调用本身
- 这个承诺函数的代码出了什么问题
- 递延和承诺函数不能正常工作
- UI-Router $stateChangeStart承诺函数
- 承诺函数给出'SyntaxError: Unexpected token}'
- 如何在茉莉花中测试javascript承诺函数
- 如何从承诺函数获得响应.然后
- 需要一些帮助,使承诺函数使用.then
- 如何在javascript函数中使用承诺函数,比如forEach reduce