Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Promise 与异步分支流程

  ES6 的 Promise 是一个神奇的概念,它不仅用于处理异步,还同时吞并了异常处理,于是就带来了种种问题。Promise 的动作有「正常」和「异常」两种状态,如果业务代码直接使用它的两种状态就变成了对 try-catch 的依赖,从而可能导致全局异常捕获抓到预料中的异常。
  首先我们要明确两个概念「预期异常」和「非预期异常」。在我的概念中,它们的区别就在于异常有没有被接住。「预期异常」表示将会被 Catch 的异常,因为我们已经预料到某处可能出现异常,所以放置了异常捕获代码,所以称为「预期异常」。除此之外就是「非预期异常」,也就是由于我们写代码时的疏忽造成一些异常没有得到正确处理而直接呈现在客户端的控制台中。这种情况属于 BUG,开发者应该即使修复程序。尽可能地将所有「非预期异常」都转换成「预期异常」。也许别人的文章中对「预期异常」和「非预期异常」的解释和我不同,但在这里这两个词的概念就同上述。
  Promise 可以有两种用法,一种是将所有业务代码都尽可能地在「正常」中处理。另一种是将业务中的异步分支使用「异常」来处理。假如我们有一只薛定谔的猫叫 schrodincat,它有一个随机的布尔属性 hasDied。于是当我们用 Promise 查询它的状态时可以有两种做法 new Promise(function(resolve){
  resolve({hasDied:Math.random()<0.5});
}).then(function(schrodincate){
  if(schrodincate.hasDied){
    // Alive
  }else{ 
    // Died
  };
},function(){
  // Damn
});
new Promise(function(resolve,reject){
  var schrodincat={hasDied:Math.random()<0.5};
  schrodincat.hasDied?resolve(schrodincat):reject(schrodincat);
}).then(function(){
  // Alive
},function(){
  // Dead
});
  其实我以前也很喜欢使用 Promise 的异常机制来处理业务中的分支逻辑,但是现在觉得这么做并不好。Promise 之所以提供 catch 只是因为异步异常无法 try-catch 捕获才提供这种方法而已。在使用 Promise 时应该尽可能的使用「正常」流程,只有当想用 try-catch 时才动用「异常」流程。比如检测一个 JSON 是否可以正确解析之类的测试性执行。
  将 catch 直接用于业务中的分支流程,会造成业务外的异常无法被区分。或者可能造成对「预期异常」的处理不得当而被全局捕获。所以我建议不要滥用 Promise 的「异常」来处理非异常流程。
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^