如何处理 promise 模式中异步调用之前发生的错误?

How to handle an error occuring before the async call in promise pattern?

经典的 promise 模式可以是(使用 Angular 的 $q 语法):

function myFunction() {
    var deferred = $q.defer();
    myAsyncCall(
        function(result) {
            deferred.resolve(result);
        },
        function(error) {
            deferred.reject(error);
        }
    );
    return deferred.promise;
}

myFunction().then(
    function(result) {
        console.log("Yeah, everything OK ! " + result);
    },
    function(error) {
        console.log("Booh, an error occured ! " + error);
    }
);

在调用异步函数之前处理条件导致错误的情况的最佳做法是什么?

示例:

function myFunction(CONDITION) {
    var deferred = $q.defer();
    if (! CONDITION) {
        /***********************
         * What to do here ???
         ***********************/
    } else {
        myAsyncCall(
            function(result) {
                deferred.resolve(result);
            },
            function(error) {
                deferred.reject(error);
            }
        );
    }
    return deferred.promise;
}

myFunction(CONDITION).then(
    function(result) {
        console.log("Yeah, everything OK ! " + result);
    },
    function(error) {
        console.log("Booh, an error occured ! " + error);
    }
);

我看到了 2 个解决方案,但其中 none 个真的很性感:

你怎么看?

可以直接调用reject,没有问题。到目前为止,这是最好的模式。例如:

function myFunction(CONDITION) {
  return new Promise(function(resolve, reject) {
    if (!CONDITION) {
      reject('The error message, or something like that');
    }
    else {
      myAsyncCall(function(result) {
        resolve(result);
      },
      function(error) {
        reject(error);
      });
    }
  });
}

我用 Q 库创建了一个片段,所以你可以看到它运行得很流畅:

document.addEventListener('DOMContentLoaded', function() {
  var div = document.querySelector('div');
  
  function myFunction(CONDITION) {
    var deferred = Q.defer();
    if (!CONDITION) {
      deferred.reject('there was an error');
    } else {
      myAsyncCall(
        function(result) {
          deferred.resolve(result);
        },
        function(error) {
          deferred.reject(error);
        }
      );
    }
    return deferred.promise;
  }

  myFunction(false).then(function(res) {
    div.innerHTML = res;
  }).catch(function(err) {
    div.innerHTML = err;
  });
});
<script src="https://raw.githubusercontent.com/kriskowal/q/v1/q.js"></script>
<div></div>