javascript – 在try块中分配值的最佳方法

let x;
try {
  x = ...;
} catch (e) { 
  return
}

// rest of the code that uses `x`
const y = x + ...;

x只分配了一次,但我必须使用let而不是const.

另一种方式是:

try {
  const x = ...;
  // rest of the code that uses `x`
  const y = x + ...;
} catch (e) { 
  return
}

但是,这会增加嵌套并使得不清楚什么会引发错误.

有没有更好的办法?

如果尝试失败,我不必关心x的值,因为我将在catch块中返回.
我也不想将其解析为单独的函数.

解决方法

功能 – 使用带有三个回调的辅助函数
function Try(attempt,onSuccess,onFailure) {
  try {
    var res = attempt();
  } catch(err) {
    return onFailure(err);
  }
  return onSuccess(res);
}

这允许你写

return Try(() => …,x => {
  // rest of the code that uses `x`
  const y = x + …;
},e => void e);

您还可以使用表示此控制流的数据结构,如Result monad(也称为Either monad):

class Result {
  constructor(go) {
    this.go = go;
  }
  static Ok(v) {
    return new this((onSuccess,_) => onSuccess(v));
  }
  static Err(r) {
    return new this((_,onFailure) => onFailure(v));
  }
  map(f) {
    return this.go(v => Result.Ok(f(v)),r => Result.Err(r));
  }
  chain(f) {
    return this.go(v => f(v),r => Result.Err(r));
  }
  unwrap() {
    return this.go(v => v,r => { throw r; });
  }
}
function Try(attempt) {
  try {
    var res = attempt();
    return Result.Ok(res);
  } catch(e) {
    return Result.Err(e);
  }
}

你可以使用它与上面简单的辅助函数非常相似:

return Try(() =>
  … // exceptions in here are caught
).go(x => {
  // rest of the code that uses `x` - exceptions are not caught
  const y = x + …;
},e => void e);

但也有更先进的链接

return Try(() =>
  … // exceptions in here are caught
).chain(x =>
  Try(() =>
    x + … // exceptions in here are caught as well
  )
).map(y =>
  … // exceptions in here are not caught
).unwrap(); // any caught exceptions are re-thrown

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...