2016-01-07 19 views
8

例を考えてみましょう:私は以下のexpress.jsアプリを持っています(下のコードを見てください)。 DBへの1つの永続的な接続と、アプリケーションライフタイム全体の間に自分自身のサービスへの1つの永続的な接続(非同期呼び出しを開始する必要があります)が必要です。また、エントリポイントがいくつかあります。つまり、HTTPプロトコルだけでなく、アプリケーションにアクセスできるエントリポイントがあります。もちろん、私はサービスの初期化コードの重複を避けたいと思っていますし、いくつかの非同期初期化サービスがあるかもしれません。上記のコードでexpress.js(または類似の)アプリケーションの非同期初期化

/* app.js */ 
var app = require('express')(); 
// set views, use routes, etc. 
var db = require('monk/mongoose/etc')(...); // happily, usually it's a sync operation 
var myService = require('./myService');  // however, it's possible to have several such services 
myService.init(function(err, result) { 
    // only here an initialization process is finished! 
}); 

module.exports.app = app; 


/* http_server.js (www entry point) */ 
var app = require('app'); 
// create an HTTP server with this app and start listening 


/* telnet_server.js (other entry point) */ 
var app = require('app'); 
// create a Telnet server with this app and start listening 

、HTTP(またはtelnet、または任意の他の)サーバが起動されるまでに、保証はmyServiceが既に初期化されたこと、ありません。

私はアプリの作成コードをどうにか再構成する必要があります。今の私は、次の解決策に固執:

/* app.js */ 
var app = require('express')(); 
module.exports.app = app; 
module.exports.init = function(callback) { 
    var myService = require('./myService'); 
    myService.init(callback);  
} 

/* entry_point.js */ 
var app = require('app'); 
app.init(function(err) { 
    if (!err) { 
     // create an HTTP/Telnet/etc server and start listening 
    } 
}); 

だから、私の質問は:起動する非同期呼び出しを必要なサービスを初期化するための一般的な方法は何ですか?

+0

これは、操作の非同期セットをシリアル化する方法とまったく変わりません。特定の順序でそれらを実行したい場合は、最初の非同期操作の完了コールバックで2回目の操作を行うか、または約束を繋ぎます。独立したN個の非同期操作がある場合は、何か他の操作を行う前にすべて実行する必要がある場合は、promisesと 'Promise.all()'を使用してください。サーバの起動と、複数の非同期操作の他の調整との違いはありません。 – jfriend00

答えて

0

このタスクで通常使用するコードのサンプルをgist hereに作成しました。 (これはQ promiseライブラリを使用しますが、他の約束事libを使うように簡単に変更することができます)。

基本的な考え方は、アプリのバックボーンを非同期初期化手順のシーケンスとして記述することです。各ステップは、1つ以上の非同期関数を呼び出し、その結果を名前にバインドします。起動プロセスは、現在のステップですべての値が解決されると次の初期化ステップに進むだけで、その後のステップでは前のステップで解決されたすべての値にアクセスできます。これにより、アプリケーション内のサービスやコンポーネントの依存関係を簡単に記述することができます。

たとえば、次のように骨格が定義することができる。

var app = [ 
    { s1: startService1 }, 
    { s2: startService2, s3: startService3 }, 
    { s4: startService4 } 
] 

は(各ステップの定義において、各機能にだけ参照が与えられていることに注意してください。start()機能 - 要旨に示される - 各を呼び出します正しい順序で機能する)。

function startService4(app) { 
    var s1 = app.s1; 
    var s2 = app.s2; 
    var deferred = Q.defer(); 
    // ... start the service, do async stuff ... 
    return deferred; 
} 

機能のアプリ引数が設定アプリバックボーンを表し、そしてからの結果:

startXxxはvarsのそれぞれは、例えば、単一の引数を取る関数であり、繰延約束を返します。以前の初期化手順は、その名前付きプロパティとして使用できます。

私はかなり複雑なシステムでこのパターンを使用しましたが、シンプルで柔軟で効果的な方法でシステムの高レベル構造を定義しています。

関連する問題