関数を公開するライブラリを管理しているとしますgetData
。ユーザーはそれを呼び出して実際のデータを取得します。
var output = getData();
内部ではデータがファイルに保存されるため、getData
Node.jsビルトインを使用して実装しますfs.readFileSync
。それは明らかだ両方getData
とfs.readFileSync
の同期機能があります。ある日、基礎となるデータソースを、非同期にのみアクセスできるMongoDBなどのリポジトリに切り替えるように言われました。また、ユーザーを怒らせるのを避けるように言われましたgetData
。APIを変更して、Promiseのみを返すか、コールバックパラメータを要求することはできません。どのようにして両方の要件を満たしますか?
コールバック/約束を使用する非同期関数は、JavasSriptとNode.jsのDNAです。自明でないJSアプリはおそらくこのコーディングスタイルに浸透しています。しかし、この実践は、いわゆる運命のコールバックピラミッドに簡単につながる可能性があります。さらに悪いことに、呼び出しチェーン内の呼び出し元のコードが非同期関数の結果に依存している場合、それらのコードもコールバック関数にラップする必要があり、呼び出し元にコーディングスタイルの制約を課します。大規模なグローバルリファクタリングを回避するために、非同期関数(サードパーティのライブラリで提供されることが多い)を同期関数にカプセル化する必要がある場合があります。この問題に関する解決策の検索は、通常、ノードファイバーで終わりましたまたはそれから派生したnpmパッケージ。しかし、ファイバーは私が直面している問題を解決できません。ファイバーの作者が提供した例でさえ、欠陥を示していました。
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
実際の出力:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
関数Fiberが非同期関数のスリープを本当に同期に変換する場合、出力は次のようになります。
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main
JSFiddleで別の簡単な例を作成し、期待される出力を生成するコードを探しました。Node.jsでのみ機能するソリューションを受け入れるので、JSFiddleで機能していなくても、npmパッケージを自由に要求できます。