2017-09-26 6 views
0

eventChannelを取り消すためにRedux Sagaの副作用のようなものを介して可能な方法はありますか? Firebaseリアルタイムデータベース"child_added"イベントこの場合、外部イベント/データ・ストリームに接続eventChannelを考慮React Redux Sagaイベントチャンネルキャンセル

// action 
const types = { SYNC: 'SYNC_TODOS' }; 
function syncTodos(todos) { 
    return { types: types.SYNC, todos } 
} 

// saga 
function todosChannel() { 
    // firebase database ref 
    const ref = firebase.database().ref('todos/'); 

    const channel = eventChannel(emit => { 
    const callback = ref.on('child_added', (data) => { 
     emit({ snapshot: data, value: data.val() }) 
    }); 

    // unsubscribe function 
    return() => ref.off('child_added', callback); 
    }); 

    return channel; 
} 

function* sync() { 
    const channel = yield call(todosChannel); 

    try { 
    while (true) { 
     const { value } = yield take(todosChannel); 
     yield put(actions.syncTodos(value)); 
    } 
    } 
    finally { 
    if(yield cancelled()) { 
     channel.close(); 
    } 
    } 
} 

export default function* rootSaga() { 
    yield fork(sync); 
} 

例えばフォークとして有効側(使用する方法はあります)ようなものでイベントチャネルを取り消し、Firebase "child_added"イベント/データストリームのリッスンを停止するアクションをlistenするtakeEvery()?またはこれは何とかチャンネルへの参照を保存し、チャンネル参照自体にcancel()を実行する必要がありますか?

ご協力いただきありがとうございます。

答えて

1

これは意味ですか?

function* sync() { 
    const channel = yield call(todosChannel); 

    yield takeEvery(channel, function*({value}){ 
    yield put(actions.syncTodos(value)) 
    } 

    yield take('CANCEL_WATCH') 
    channel.close(); 
} 

BTW、takeEveryは効果がありません。

+0

これは本当にきれいです、ありがとうございます!私が条件付きでチャンネルの作成を実行したいのであれば、 'yield call(todosChannel)'の前に 'yield take( 'SOME_ACITON')'を置くことができますか? –

+0

to alex:はい、 'take'はブロック効果です。 – cyrilluce