2017-04-25 1 views
0

現在のプロジェクトでは、firebase websocketサブスクリプションを扱っています。異なるコンポーネントは、異なるデータにサブスクライブすることができます。すべての項目のリストでListItemのコンポーネントは、SUBSCRIBEアクションをにディスパッチし、UNSUBSCRIBEアクションをディスパッチすることによってサブセッションをcomponentWillUnmountにディスパッチすることによって、その特定のアイテムのwebsocket "イベント"をサブスクライブします。redux-sagaで多数のイベントへのサブスクリプション/サブスクリプションの処理

マイサガは、次のようになります。

const subscriptions = {} 

export function * subscribeLoop() { 
    while (true) { 
    const { path } = yield take(SUBSCRIBE) 
    subscriptions[path] = yield fork(subscription, path) 
    } 
} 

export function * unsubscribeLoop() { 
    while (true) { 
    const { path } = yield take(UNSUBSCRIBE) 
    yield cancel(subscriptions[path]) 
    } 
} 

export function * subscription (path) { 
    let ref 

    try { 
    const updateChannel = channel() 

    ref = api.child(path) 
    ref.on('value', snapshot => { 
     updateChannel.put(snapshot.val()) 
    }) 

    while (true) { 
     const data = yield take(updateChannel) 
     yield put(handleUpdate(path, data)) 
    } 
    } finally { 
    if (yield cancelled()) { 
     ref.off() 
     ref = null 
    } 
    } 
} 

私は、これはこれに対処するための正しい方法ではないと仮定 - それは、500の項目のリストに確かにかなり遅いです。

パフォーマンスを最適化するにはどうすればよいですか?

  • フォークする必要がありますか?
  • 他のものを処理するためのスペースをスレッドに与えるために何らかの遅延を導入すべきでしょうか?

ヒントはありがたいです。

答えて

0

スレッドにいくつかのスペースを与えるために何らかの遅延を導入すべきですか>他のものを処理するには?

まず、フォークが実際に無限ループにねじれられる任意のスレッドを作成しないようにReduxのサガとエフェクトの使用を覚えておく必要があるすべての。 yield演算子がオブジェクトの両側を渡すので、コールバックの連鎖の構成のための構文的な砂糖だけです。このような観点から、強制的な遅延の問題はスレッドとしては意味がなく、存在しません。

フォークする必要がありますか?

コールスキルの設定なしで、一般的に1つのルートサガですべてを行うことができます。このアイデアは、websocketの現在の語彙領域でコールバック関数を使ってサブスクリプションを作成し、遅延約束に基づいて疑似無限ループでメッセージを取得することを期待することです。

概念的コードは約そう見ることができます:

const subscribers = new Map() 

function * webSocketLoop() { 
    let resolver = null 
    let promise = new Promise(resolve => (resolver = resolve)) 
    let message = null; 

    websocket.on('message', (payload) => { 
    message = Object.assign({}, payload) 
    resolver() 
    promise = promise.then(() => new Promise(resolve => (resolver = resolve))) 
    }) 

    while(true) { 
    yield call(() => promise) 
    const type = message.type 
    const handlers = subscribers.get(type) || [] 
    handlers.forEach(func => func(message)) 
    } 
} 

export function * mainSaga() { 
    yield takeEvery(SUBSCRIBE, subscribe) 
    yield takeEvery(UNSUBSCRIBE, unsubscribe) 
    yield fork(webSocketLoop) 
}