[解決済み] コンストラクタ関数が Promise を返すのは悪い習慣ですか?
質問
ブログプラットフォーム用のコンストラクタを作成しようとしていますが、内部で多くの非同期処理が行われています。これらは、ディレクトリから投稿を取得し、それらを解析し、テンプレートエンジンを介してそれらを送信するなど、多岐にわたります。
そこで質問なのですが、コンストラクタの関数が、呼び出した関数のオブジェクトではなく、プロミスを返すようにすることは賢明ではないのでしょうか?
new
に対してです。
例えば、こんな感じです。
var engine = new Engine({path: '/path/to/posts'}).then(function (eng) {
// allow user to interact with the newly created engine object inside 'then'
engine.showPostsOnOnePage();
});
さて、ユーザーは次のようなこともできます。 ない 補足 プロミスチェーンリンクを供給する。
var engine = new Engine({path: '/path/to/posts'});
// ERROR
// engine will not be available as an Engine object here
この場合、ユーザーはなぜこのような問題が発生したのかわからなくなります。
engine
が構築後に利用できなくなる。
コンストラクタでPromiseを使用する理由は理にかなっています。ブログ全体が構築段階の後でも機能するようにしたいからです。しかし、このように
new
.
私は、次のようなものを使うことを検討しました。
engine.start().then()
または
engine.init()
を使えば、代わりにプロミスを返します。しかし、これらも胡散臭く感じます。
編集:これはNode.jsのプロジェクトでの話です。
解決方法は?
そう、これは悪い習慣なのです。コンストラクタはそのクラスのインスタンスを返すべきで、それ以外のものを返してはいけません。これは
new
演算子
であり、それ以外は継承される。
さらに、コンストラクタは新しいインスタンスの作成と初期化のみを行う必要があります。データ構造とインスタンス固有のプロパティをすべてセットアップする必要がありますが 実行しない タスクを実行します。それは 純粋関数 可能であれば副作用を排除し、そのメリットを享受してください。
コンストラクタから実行したい場合はどうすればいいですか?
それはあなたのクラスのメソッドに入れるべきです。グローバルな状態を変化させたいのですか?それなら、オブジェクト生成の副作用としてではなく、明示的にそのプロシージャを呼び出します。この呼び出しは、インスタンス化の直後に行うことができます。
var engine = new Engine()
engine.displayPosts();
そのタスクが非同期であれば、メソッドからその結果のプロミスを返すことで、簡単に終了まで待つことができるようになりました。
しかし、このパターンは、メソッドが(非同期に)インスタンスを変異させ、他のメソッドがそれに依存する場合にはお勧めしません。なぜなら、他のメソッドは待つことを要求され(実際には同期であっても非同期になる)、すぐに内部キュー管理が行われることになるからです。インスタンスが存在しても、実際には使用できないようなコーディングはしないでください。
データを非同期でインスタンスにロードしたい場合はどうすればよいですか?
自問自答してください。 データ無しのインスタンスが実際に必要ですか?どうにかして使うことはできないか?
もし、その答えが いいえ であれば、データが揃う前に作成するべきではありません。データを取得する方法をコンストラクタに指示する(あるいはデータのプロミスを渡す)のではなく、データ自身をコンストラクタのパラメータにするのです。
次に、静的メソッドを使用してデータをロードし、そこからプロミスを返します。そして、データを新しいインスタンスにラップする呼び出しを、その上でチェーンさせます。
Engine.load({path: '/path/to/posts'}).then(function(posts) {
new Engine(posts).displayPosts();
});
これにより、データの取得方法をより柔軟に変更できるようになり、コンストラクタも大幅に簡素化されます。同じように、プロミスを返す静的ファクトリー関数を書いて
Engine
インスタンスを作成します。
Engine.fromPosts = function(options) {
return ajax(options.path).then(Engine.parsePosts).then(function(posts) {
return new Engine(posts, options);
});
};
…
Engine.fromPosts({path: '/path/to/posts'}).then(function(engine) {
engine.registerWith(framework).then(function(framePage) {
engine.showPostsOn(framePage);
});
});
関連
-
vue for 登録ページ効果 vue for sms 認証コードログイン
-
Vueのイベント処理とイベントモディファイアの解説
-
[解決済み】Node.js Error: Cannot find module express
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】<select>で現在選択されている<option>をJavaScriptで取得するにはどうすればよいですか?
-
[解決済み] 抽象クラスはコンストラクタを持つことができますか?
-
[解決済み] なぜJavaScriptのeval関数を使うとダメなのか?
-
[解決済み] JavascriptのPromiseを関数スコープ外で解決する
-
[解決済み] なぜdocument.writeは「バッドプラクティス」と言われるのですか?
-
[解決済み】JavaScriptの関数名を文字列で指定して実行する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vueの要素ツリーコントロールに破線を追加する説明
-
jsを使った簡単な照明スイッチのコード
-
WeChatアプレット用ユニアプリによるグローバルシェアリング
-
vueディレクティブv-bindの使用と注意点
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み】Node.jsで "Cannot find module "エラーを解決するには?
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
[解決済み】React Uncaught Error: 対象コンテナが DOM 要素でない [重複]。
-
モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory, scandir 'D:\.... \node_modules
-
jq は html ページとデータを動的に分割する。