如何处理Parse promise错误,使它们不会'不要一直执行代码

How do you handle Parse promise errors so they don't keep executing code?

本文关键字:代码 执行 一直 处理 何处理 Parse 错误 promise      更新时间:2023-09-26

假设我有一个Parse Cloud Code js函数,我想返回一个promise,比如:

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
}

如何重构/重写它以更好地处理位置C、E和G的情况

我意识到我可以在C和E中使用dsPromise.rejectt(),但当前正在执行的promise链会发生什么?它不是会继续执行并转到D、E、F、G等吗。?那么我就不能到达一个我正在多次解析dsPromise的地方吗?

我如何重构/重写它以更好地处理位置C、E和G的情况?

适当嵌套处理程序。如果一个处理程序应该只处理一个操作的解析,那么直接在该操作的promise上用.then将其链接起来,而不是在链中的其他地方。

在位置E中,您不会将处理程序附加到包含save调用的链,而只会附加到onFulfilled(即未中止)分支中的promise。

doSomethingCruciallyImportant().then(function(){
    // location "F"
    // at this point we know doSomethingCruciallyImportant succeeded
    return doSomethingUnimportant();
}, function(error){
    // location "G"
    // not sure if we got here because doSomethingCruciallyImportant() errored
    // or because doSomethingUnimportant() errored.
});

没有。阅读更多关于.then()onRejection处理程序实际工作方式的信息-在执行onFulfilled处理程序(此处调用doSomethingUnimportant())时,它不是调用的。在位置G中,您可以肯定地知道,在then调用失败之前,链中的某个东西——在我的简化片段中是doSomethingCruciallyImportant()

组合:

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;
  });
}