2017-04-25 13 views
0

현재 프로젝트에서는 firebase websocket subscription을 다루고 있습니다. 다른 구성 요소는 다른 데이터에 가입 할 수 있습니다 (예 : 모든 항목의 목록에있는 ListItem 구성 요소는 SUBSCRIBE 작업을 에 디스패치하고 UNSUBSCRIBE 작업을 componentWillUnmount에 디스패치하여 수신 거부를 설정하여 해당 특정 항목에 대한 웹 소켓 "이벤트"를 구독합니다.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 
    } 
    } 
} 

I는이 처리 할 수있는 권리 방법이 아니다 가정 - 그것은 참으로 500 개 항목의 목록에 다소 느립니다.

어떻게 성능을 최적화 할 수 있습니까?

  • 포크가 필요합니까?
  • 스레드에게 다른 것들을 처리 할 공간을주기 위해 일종의 지연을 도입해야합니까?

모든 힌트를 부탁드립니다.

답변

0

다른 것들을 처리하기 위해 스레드에게 약간의 지연을주기 위해 어떤 종류의 지연을 도입해야합니까?

첫째는 포크 실제로 무한 루프에 트위스트 될 수있는 스레드를 생성하지 않습니다처럼 REDUX 사가 효과의 사용을 기억하는 것이 필요하다 모두. yield 연산자가 양측에서 전달하는 객체를 제공 할 때 콜백 체인을 구성하기위한 문법적 설탕 일뿐입니다. 이러한 관점에서 볼 때 강제 지연 문제는 스레드로 존재하지 않고 의미가 없습니다.

포크가 필요합니까?

정교한 기술의 경우 일반적으로 통화 포크를 설정하지 않고 하나의 루트 사가에서 모든 작업을 수행 할 수 있습니다. 이 아이디어는 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) 
}