我经常发现自己使用以下形式的promise编写beforeSave
和afterSave
:
beforeSavePromise: function (request) {
var recipe = request.object;
var promises = [
doFooIfNeeded(recipe),
doBarIfNeeded(recipe),
doQuuxIfNeeded(recipe)
];
return Parse.Promise.when(promises)
},
其中的每一个都是条件操作,仅在特定字段脏时执行操作。例如,doFooIfNeeded
可能看起来像:
if (recipe.dirty('imageFile')) {
return /* some Promise that updates thumbnails of this image */;
} else {
return Parse.Promise.as(); // The no-op Promise. Do nothing!
}
我的问题是,Parse.Promise.as()
真的是无操作Promise
吗?还是new Parse.Promise()
更正确?
由于所有"脏"结果都为聚合贡献了一个已解析的承诺,您可以选择以下任何方式为每个"干净"结果贡献:
- 不在阵列中放置任何东西
- 在数组中放入一个值
- 在数组中放入已解决的承诺
- 在数组中放入一个被拒绝的承诺
(1) ,(2)和(3)将保证聚合的promise在不考虑干净/脏输出的情况下解决(除了一些不可预测的错误)。
(4) 只有当所有结果都是"肮脏的"时,才会导致愤怒的承诺得到解决,或者一旦出现任何一个"干净的"结果,就会拒绝。
实际上,可以在(2)和(4)之间进行选择,这取决于您希望聚合承诺的行为方式。(1) 将使聚合过程复杂化,并且(3)将是不必要的昂贵。
当所有东西都已经"干净"或已经清理时,聚合承诺似乎是合适的,因此我建议(2),在这种情况下,您的foo()
/bar()
/quux()
函数可以写如下:
function foo() {
return recipe.dirty('imageFile') ? updates_thumbnails() : true; // doesn't have to be `true` or even truthy - could be almost anything except a rejected promise.
}
并汇总问题中的结果:
$.when([ foo(recipe), bar(recipe), quux(recipe) ]).then(function() {
//all thumbnails were successfully updated.
}).fail(function() {
//an unexpected error occurred in foo(), bar() or quux().
});
Parse.Promise.as()
将从技术上为您提供一个状态设置为resolved
的Promise。当您返回此Promise时,它的回调将被成功触发。您可以提供一个值作为参数,该参数基本上会用该值触发回调。根据Promise创建的Parse指南,new Parse.Promise()
创建一个Promise,其状态为,且既不设置为resolved
也不设置为failed
。这使您可以根据需要灵活地手动管理其状态。