最近、Golangのif err != nil
がどうのこうのと盛り上がっていますが、いかがお過ごしでしょうか?エラーを多値で返すのは面白いですね。
jsでもこれを実現するライブラリを書いてみました。
akameco/golangify: Golang like error handling for async/await
$ yarn add golangify
const go = require('golangify')
const success = x => Promise.resolve(x + x)
const failure = () => Promise.reject(new Error('err'))
const main = async () => {
console.log(await go(success)(1))
// => [ 2, null ]
const [result, err] = await go(failure)()
if (err !== null) {
console.log(err.message)
// => err
}
console.log(result)
// => null
}
main()
はい、golangify
でラップされたasyncな関数はその関数の結果とエラーを多値で返します。
const [result, err] = await go(failure)()
エラーがない場合は[result, null]
、エラーがある場合は、[null, error]
を返します。
面倒なのでsync関数は対応してないですが、実装自体はシンプルです。
const golangify = target => new Proxy(target, {
apply(target, prop, args) {
const result = Reflect.apply(target, prop, args)
return result.then
? result.then(v => [v, null]).catch(err => [null, err])
: result
},
})
Reflect.apply
で実行して、Promise
ならばそれを解決してthen/catchでそれぞれ配列を返すようにしてるだけです。
Proxyを使うとメタ的な処理を追加できるので楽しいですね。
おわり
気が向いたらスターしてください。
akameco/golangify: Golang like error handling for async/await
うるせぇお前がGo言語になるんだよ https://t.co/KVFjvg614F pic.twitter.com/5nURgUDsxk
— あかめ@17時退勤.js (@akameco) July 22, 2018
だいたいReflectを使うとダークサイドに落ちるので普通に使わないほうがいい
— あかめ@17時退勤.js (@akameco) July 19, 2018