问题描述
假设我有一个 Parse Cloud Code js 函数,我想返回一个承诺,例如:
function doSomething(myObj, abortIfSaveFails) {var dsPromise = new Parse.Promise();myObj.set("name", "abc");myObj.save().then(function(){//位置A"//太好了,成功了!//不想在这个块中做更多的事情,因为//即使保存失败,我们也可能想做同样的事情,而我//不想重复代码返回 Parse.Promise.as();}, 函数(错误){//位置B"//保存失败,但我们可能想继续如果(abortIfSaveFails){//位置C":希望我能在这里中止整个承诺链!返回 Parse.Promise.error();} 别的 {返回 Parse.Promise.as();}}).then(函数(){//位置D"//此时我们不确定是否保存成功,但让我们//假设我们不需要知道返回 doSomethingCruciallyImportantAndReturnAPromise();}, 函数(错误){//位置 "E"://不确定我们是否到达这里是因为 doSomethingCruciallyImportant...() 出错或//因为 myObj.save() 出错了.//现在中止整个事情会很好!返回 Parse.Promise.error();}).then(函数(){//位置F"//此时我们知道 doSomethingElse... 成功返回 doSomethingUnimportantAndReturnAPromise();}, 函数(错误){//位置G"//不确定我们是否到达这里是因为 doSomethingCruciallyImportant...() 出错或//因为 doSomethingUnimportant...() 出错了.//如果 doSomethingCruciallyImportant...() 成功但 doSomethingUnimportant...()//失败,我想做 dsPromise.resolve()...但我无法解决,因为//我们可能正在中止函数,因为 myObj.save() 拒绝了,//或者 doSomethingCruciallyImportant 被拒绝!dsPromise.reject();//可能不是我想做的!}).then(函数(){//位置 "H"//一切正常dsPromise.resolve();});//位置我"返回 dsPromise;//返回承诺,所以 `then` 将等待}
我如何重构/重写它以更好地处理位置 C、E 和 G 的情况?
我意识到我可以在 C 和 E 上使用 dsPromise.reject(),但是当前正在执行的承诺链会发生什么?它不会继续执行并继续执行 D、E、F、G 等吗?那么我不能到达我多次解析 dsPromise 的地方吗?
适当地嵌套处理程序.如果处理程序应该只处理单个操作的解析,则将其与 .then
直接链接到该操作的承诺上,而不是链中的其他地方.
在位置 E 中,您不会将处理程序附加到包含保存调用的链,而只会附加到 onFulfilled
(即未中止)分支中的承诺.
doSomethingCruciallyImportant().then(function(){//位置F"//此时我们知道 doSomethingCruciallyImportant 成功了返回 doSomethingUnimportant();}, 函数(错误){//位置G"//不确定我们是否到达这里,因为 doSomethingCruciallyImportant() 出错了//或者因为 doSomethingUnimportant() 出错了.});
没有.阅读更多,了解 .then()
的 onRejection
处理程序如何实际上有效 - 当 onFulfilled
处理程序被执行时它不被调用(这里调用 doSomethingUnimportant()
).在位置 G,您肯定知道在 then
调用失败之前链中的某些内容 - 在我的简化片段中的 doSomethingCruciallyImportant()
.
组合:
function doSomething(myObj, abortIfSaveFails) {myObj.set("name", "abc");return myObj.save().then(null,//根本没有 onFulfilled 块!功能(错误){如果(abortIfSaveFails){返回 Parse.Promise.error();//中止} 别的 {返回 Parse.Promise.as();//不管保存失败都会继续}}).那么(函数(){//要么保存成功,要么我们不关心它返回 doSomethingCruciallyImportantAndReturnAPromise().then(函数(){//位置F"//此时我们知道 doSomethingCruciallyImportant 成功了返回 doSomethingUnimportantAndReturnAPromise().then(null, function(err) {返回 Parse.Promise.as();//我们不在乎它是否出错});}//, 函数(错误){//位置G"//doSomethingCruciallyImportant...() 出错//返回 Parse.Promise.error();//});}).then(函数(结果){//位置 "H"//一切正常:保存成功(或者我们不在乎)并且//doSomethigCruciallyImportant() 也做了返回结果;});}
Let's suppose I have a Parse Cloud Code js function which I want to return a promise, like:
function doSomething(myObj, abortIfSaveFails) {
var dsPromise = new Parse.Promise();
myObj.set("name", "abc");
myObj.save().then(function(){
// location "A"
// great, it worked!
// don't want to actually do anything more in this block because
// we might want to do the same things even if save fails, and I
// don't want to repeat code
return Parse.Promise.as();
}, function(error){
// location "B"
// save failed, but we might want to keep going
if (abortIfSaveFails) {
// location "C": wish I could abort the whole promise chain here!
return Parse.Promise.error();
} else {
return Parse.Promise.as();
}
}).then(function(){
// location "D"
// at this point we're not sure if save succeeded but let's
// assume we don't need to know
return doSomethingCruciallyImportantAndReturnAPromise();
}, function(error){
// location "E":
// not sure if we got here because doSomethingCruciallyImportant...() errored or
// because myObj.save() errored.
// would be nice to abort the whole thing right now!
return Parse.Promise.error();
}).then(function(){
// location "F"
// at this point we know doSomethingElse... succeeded
return doSomethingUnimportantAndReturnAPromise();
}, function(error){
// location "G"
// not sure if we got here because doSomethingCruciallyImportant...() errored or
// because doSomethingUnimportant...() errored.
// If doSomethingCruciallyImportant...() succeeded but doSomethingUnimportant...()
// failed, I'd LIKE to do dsPromise.resolve()... but I can't resolve, because
// we might be in the process of aborting the function because myObj.save() rejected,
// or doSomethingCruciallyImportant rejected!
dsPromise.reject(); // might not be what I want to do!
}).then(function(){
// location "H"
// everything worked fine
dsPromise.resolve();
});
// location "I"
return dsPromise; // return the promise so `then` will wait
}
How can I refactor/rewrite this to better handle the situations at locations C, E, and G?
I realize I could dsPromise.reject() at C and E, but what would happen to the currently executing promise chain? Wouldn't it keep executing and move on to D, E, F, G etc.? Then couldn't I get to a place where I'm resolving dsPromise multiple times?
Nest handlers appropriately. If a handler is supposed to handle the resolution of only a single action, then chain it with .then
directly on the promise for that action, and not somewhere else in the chain.
In location E, you would not attach a handler to the chain that includes the save call, but only to promises in the onFulfilled
(i.e. not aborted) branch.
No. Read more about how the onRejection
handler of .then()
actually works - it is not called when the onFulfilled
handler is executed (which calls doSomethingUnimportant()
here). In location G, you know for sure that something in the chain before the then
call failed - doSomethingCruciallyImportant()
in my simplified snippet.
In combination:
function doSomething(myObj, abortIfSaveFails) {
myObj.set("name", "abc");
return myObj.save().then(null, // no onFulfilled block at all!
function(error){
if (abortIfSaveFails) {
return Parse.Promise.error(); // abort
} else {
return Parse.Promise.as(); // keep going regardless of the save fail
}
}).then(function() {
// either save succeeded or we don't care about it
return doSomethingCruciallyImportantAndReturnAPromise()
.then(function(){
// location "F"
// at this point we know doSomethingCruciallyImportant succeeded
return doSomethingUnimportantAndReturnAPromise().then(null, function(err) {
return Parse.Promise.as(); // we don't care if it errored
});
} //, function(error){
// location "G"
// doSomethingCruciallyImportant...() errored
// return Parse.Promise.error();
// }
);
}).then(function(result) {
// location "H"
// everything worked fine: Save succeeded (or we didn't care) and
// doSomethigCruciallyImportant() did as well
return result;
});
}
这篇关于您如何处理 Parse 承诺错误,以免它们继续执行代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!