LoginSignup
3
1

More than 5 years have passed since last update.

非同期処理を含む関数を書く時は、迷ったらpromiseをreturnしよう

Posted at

JavaScriptは非同期処理が基本の言語です。
非同期処理が基本であるがゆえ、同期的な言語では書けないような効率的なコードを書くことができます。

ですが、非同期処理は結果をコールバックで扱うためいわゆるコールバック地獄に陥りがちです。
これはPromiseという仕組みを使うと少し楽ができます。
参考: Promiseと仲良くなって気持ち良く非同期処理を書こう

さて、ここからが本題。
JavaScriptのライブラリ作者の方にお願いがあります。

非同期処理を含む関数(メソッド)を書いたとき、戻り値に迷ったらPromiseをreturnしてほしい! ということです。

例えばJavaScriptの汎用バリデータライブラリであるvalidatorjsでは、カスタムルールとして非同期処理(例: DBに問い合わせを行ってユーザ名の重複をチェックする)を含むルールを作成することができます。
https://github.com/skaterdav85/validatorjs#asynchronous-validation

ところがcheck()メソッドがこのルールに対応していません。わざわざcheckAsync()という別メソッドを準備して非同期的ルールを処理しています。
もしcheck()メソッドがpromiseを返していれば、非同期ルールがあるないに関わらず

var v = new Validator(/* data */, /* rules */);
v.check()
    .then(function(){
        // validation が通った場合
    })
    .catch(function(){
        // validation に失敗した場合
    });

のような書き方ができます。

各ルールはtrue/false(同期的ルール)かPromise(非同期的ルール)をreturnする。ということにすれば、check()メソッドは以下のように統一的に実装できます。

  • とりあえず新規にPromiseをreturnする。(*)
  • ルールを評価する。
  • Promiseを返すルールがあった場合はPromise.all()でそれらの結果を待つ。
  • 全てのルールの結果が揃ったら、(*)のPromiseに対してresolve()またはreject()をコール。

数年前に自分用に書いたバリデーションライブラリでは(jQueryのPromiseベースですが)同じようなことをやってました。
時間があったらvalidatorjsを改造してみたいと思います。

同じようなリファクタリングをした人もいるみたいです。 https://github.com/skaterdav85/validatorjs/issues/106
次のバージョンではこのアプローチを採用してほしいところですね。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1