We refactor a function that uses try/catch to a single composed expression using Either. We then introduce the chain function to deal with nested Eithers resulting from two try/catch calls.

For example we have this code using try & catch:

const getPort = () => {
try {
const file = fs.readFileSync('config.json');
const c = JSON.parse(file);
return c.port;
} catch(e) {
return ;
}
}

And now, we want to use Either to rewirte the code:

// SETUP: fake fs
//==========
const fs = {
readFileSync: name => {
if(name === 'config.json') {
return JSON.stringify({port: })
} else {
throw('missing file!')
}
}
} //================= const Right = x => ({
map: f => Right(f(x)),
fold: (f, g) => g(x),
toString: () => `Right(${x})`
}); const Left = x => ({
map: f => Left(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`
}); const fromNullable = x =>
x != null ? Right(x): Left(null); const tryCatch = f => {
try {
return Right(f());
} catch(e) {
return Left(e);
}
} //=========================
const getPort = () =>
tryCatch(() => fs.readFileSync('config.json'))
.map(f => JSON.parse(f))
.fold(
x => ,
x => x.port); console.log(getPort('config.json'))

We wrote the function 'tryCatch', the idea is put the code need to be checked in try, when success call 'Right', error, call 'Left()'.

tryCatch(() => fs.readFileSync('config.json'))

Read the file, is success, will return file content. If not, then goes to set default 3000.

  .fold(
x => ,
x => x.port);

It works, but we still miss one things, in the old code, the 'JSON.parse' are also wrapped into try catch.

const getPort = () =>
tryCatch(() => fs.readFileSync('config.json')) //Right('{port:8888}')
.map(f => tryCatach(() => JSON.parse(f))) //Right(Right({port:8888}))

But once we also wrap parseing code into tryCatch function, the return value is 2d-Right. So we want to flatten it.

const Right = x => ({
map: f => Right(f(x)),
flatMap: f => f(x),
fold: (f, g) => g(x),
toString: () => `Right(${x})`
}); const Left = x => ({
map: f => Left(x),
flatMap: f => f(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`
});

We add 'flatMap', so instead of putting the value into Right() or Left(), we just return the value. Because we know the value passed in is already a Right or Left.

const getPort = () =>
tryCatch(() => fs.readFileSync('config.json')) //Right('{port:8888}')
.flatMap(f => tryCatch(() => JSON.parse(f))) //Right({port:8888})
.fold(
x => ,
x => x.port);

---------

// SETUP: fake fs
//==========
const fs = {
readFileSync: name => {
if(name === 'config.json') {
return JSON.stringify({port: })
} else {
throw('missing file!')
}
}
} //================= const Right = x => ({
map: f => Right(f(x)),
flatMap: f => f(x),
fold: (f, g) => g(x),
toString: () => `Right(${x})`
}); const Left = x => ({
map: f => Left(x),
flatMap: f => f(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`
}); const fromNullable = x =>
x != null ? Right(x): Left(null); const tryCatch = f => {
try {
return Right(f());
} catch(e) {
return Left(e);
}
} //=========================
const getPort = () =>
tryCatch(() => fs.readFileSync('config.json')) //Right({port:8888})
.flatMap(f => tryCatch(() => JSON.parse(f))) //Right(Right({port:8888}))
.fold(
x => ,
x => x.port); console.log(getPort('config.json'))

-----

You can also rename 'flatMap' to 'chain'. Sometime 'flatMap' or 'chain' looks similar to 'fold' implementation. But the meaning is different, here 'chain / flatMap' says It says, "If we're going to return another Either, we are going to use chain instead of map." 'fold' says just get the value out of the box, it's done!

[JS Compose] 3. Use chain for composable error handling with nested Eithers (flatMap)的更多相关文章

  1. JS function document.onclick(){}报错Syntax error on token "function", delete this token

    JS function document.onclick(){}报错Syntax error on token "function", delete this token func ...

  2. JS function document.onclick(){}报错Syntax error on token "function", delete this token - CSDN博客

    原文:JS function document.onclick(){}报错Syntax error on token "function", delete this token - ...

  3. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  4. Erlang error handling

    Erlang error handling Contents Preface try-catch Process link Erlang-way error handling OTP supervis ...

  5. MySQL Error Handling in Stored Procedures 2

    Summary: this tutorial shows you how to use MySQL handler to handle exceptions or errors encountered ...

  6. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto

    目录 . 应用场景 . Use Case Code Analysis . 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer Over ...

  7. Error Handling

    Use Exceptions Rather Than Return Codes Back in the distant past there were many languages that didn ...

  8. Error Handling and Exception

    The default error handling in PHP is very simple.An error message with filename, line number and a m ...

  9. Clean Code–Chapter 7 Error Handling

    Error handling is important, but if it obscures logic, it's wrong. Use Exceptions Rather Than Return ...

随机推荐

  1. 洛谷P2234 [HNOI2002] 营业额统计 [splay]

    题目传送门 营业额统计 题目描述 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天 ...

  2. iOS 9音频应用开发基础教程

    iOS 9音频应用开发基础教程(大学霸内部资料)   介绍:iOS 9音频应用开发基础教程(内部资料)是iOS 9音频应用开发专向教程.本书采用Swift 2.0语言开发基于iOS 9的音频应用.实现 ...

  3. Javascript 中的神器

    Promise in js 回调函数真正的问题在于他剥夺了我们使用 return 和 throw 这些关键字的能力.而 Promise 很好地解决了这一切. 2015 年 6 月,ECMAScript ...

  4. Cable master POJ - 1064

    Inhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Commi ...

  5. hdu 3089 (快速约瑟夫环)

    Josephus again Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. 【manacher+FFT】BZOJ3160-万径人踪灭

    [题目大意] 在一个仅仅含有a,b的字符串里选取一个子序列,使得: 1.位置和字符都关于某条对称轴对称: 2.不能是连续的一段. [思路] 不连续的回文串的个数=总的回文串个数-连续回文串的个数. 后 ...

  7. [NC13C]形态形成场/[Gym100430B]Divisible Substrings

    [NC13C]形态形成场/[Gym100430B]Divisible Substrings 题目大意: 有\(m(m\le26)\)个字符串替换式\(S_i(|S_i\le100|)\),表示某个大写 ...

  8. HDU 5305 Friends dfs

    Friends 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5305 Description There are n people and m pa ...

  9. 2015 UESTC 数据结构专题B题 秋实大哥与花 线段树 区间加,区间查询和

    B - 秋实大哥与花 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 De ...

  10. YII 关联查询

    通过外键自己关联自己