関数を公開するライブラリを維持しているとしますgetData
。ユーザーは実際のデータを取得するためにそれを呼び出します:
var output = getData();
内部データはファイルに保存されるため、getData
Node.js 組み込み を使用して実装しますfs.readFileSync
。どちらも明らかでgetData
ありfs.readFileSync
、同期機能です。ある日、基になるデータ ソースを、非同期でのみアクセスできる MongoDB などのリポジトリに切り替えるように言われました。また、ユーザーを怒らせないようにと言われましたgetData
。API を変更して、単に promise を返したり、コールバック パラメーターを要求したりすることはできません。どうすれば両方の要件を満たすことができますか?
callback/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)
関数ファイバーが実際に非同期関数スリープを同期に変える場合、出力は次のようになります。
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 パッケージを自由に要求できます。