2017-12-07 18 views
6

다운로드 관리자의 예를 들어 보겠습니다. 활성 다운로드는 여러 번있을 수 있습니다.idiomatic redux를 사용하여 대기열 및 취소 이벤트를 관찰 할 수 있습니다.

작업을 시작하고 중지하고 완료를 표시하고 특정 다운로드의 다운로드 진행률을 표시 할 수 있습니다.

const START_DOWNLOAD = "START_DOWNLOAD"; 
const startDownload = payload => ({ type: START_DOWNLOAD, payload }); 

const DOWNLOAD_PROGRESS = "DOWNLOAD_PROGRESS"; 
const downloadProgress = payload => ({ type: DOWNLOAD_PROGRESS, payload }); 

const STOP_DOWNLOAD = "STOP_DOWNLOAD"; 
const stopDownload = payload => ({ type: STOP_DOWNLOAD, payload }); 

const COMPLETE_DOWNLOAD = "COMPLETE_DOWNLOAD"; 
const completeDownload = payload => ({ type: COMPLETE_DOWNLOAD payload }); 

이러한 작업은 다운로드를 식별하는 ID를 포함하고 다음 감속기를 사용하여 REDUX 상태를 수정할 수 있습니다

const downloadReducer = (state = initialState, action) => { 
    switch (action.type) { 
    case STOP_DOWNLOAD: 
     return { 
     ...state, 
     [action.payload.id]: { 
      state: "IDLE", 
     }, 
     }; 

    case START_DOWNLOAD: 
     return { 
     ...state, 
     [action.payload.id]: { 
      state: "IN_PROGRESS", 
      progress: 0, 
     }, 
     }; 

    case DOWNLOAD_PROGRESS: 
     return { 
     ...state, 
     [action.payload.id]: { 
      state: "IN_PROGRESS", 
      progress: action.payload.progress, 
     }, 
     }; 

    case COMPLETE_DOWNLOAD: 
     return { 
     ...state, 
     [action.payload.id]: { 
      state: "DONE", 
      progress: 100, 
     }, 
     }; 

    default: 
     return state; 
    } 
}; 

지금 사용하여 이러한 작업의 비동기 파견을 관리하는 방법에 문제가 온다 관측 가능하다.

예를 들어 우리는 이런 식으로 뭔가를 할 수 :

const downloadEpic = action$ => 
    action$.ofType(START_DOWNLOAD).mergeMap(action => 
    downloader 
    .takeUntil(
     action$.filter(
     stop => 
     stop.type === STOP_DOWNLOAD && 
     stop.payload.id === action.payload.id, 
    ), 
    ) 
    .map(progress => { 
     if (progress === 100) { 
     return completeDownload({ 
      id: action.payload.id 
     }); 
     } else { 
     return downloadProgress({ 
      id: action.payload.id, 
      progress 
     }); 
     } 
    }), 
); 

이 작동합니다. 그러나 허용되는 활성 다운로드 수를 제한하려면 어떻게해야합니까? mergeMapconcatMap으로 대체하면 한 번에 하나의 활성 다운로드 만 허용 할 수 있습니다. 또는 concurrent parametermergeMap에 제공하고 내부 다운로더 관찰 가능 항목의 실행 횟수를 정확히 지정할 수 있습니다.

그러나이 문제는 현재 대기중인 다운로드를 중단 할 수 없다는 문제가 있습니다.

I have created a complete working example that you can try here.

는 어떻게 제한 할 수 있습니다 및 대기열 다운로드 가능한 가장 관용적 인 방법으로 rxjs 및 REDUX 관찰을 사용하고 계십니까?

+1

나는 RXJS와 이야기 할 수는 없지만 상점을 정규화하고, ID로 다운로드를 저장하고, 활성 다운로드를 저장하고, 다운로드 된 대기열에 저장된 다운로드를 ID 배열에 저장 한 다음 Redux 썽크와 같은 미들웨어를 사용하여 상태를 읽을 수 있습니다 대기열에있는 최대 다운로드에 도달했는지 확인한 다음 해당 작업을 발송하십시오. 원할 경우 RxJ없이 답을 제공 할 수 있습니까? –

+1

@ matthew-brent 그러나이 문제에 대한 해결책에는 관심이없고 관용적 인 관행을 사용하여이를 해결할 수있는 방법에 더 관심이 있습니다. – Eamonn

+0

돌아 오는 상점으로 바 부 패턴을 포함한다. store.subscribe를 사용하여 저장소 변경 내용을 수신 할 수 있습니다. 아마도 라이브러리의 기존 기능을 사용할 수있을 때 동일한 기능을 다시 쓰는 이유는 무엇일까요? –

답변

2

나는 이것을 며칠 동안보고 있었지만 상대적으로 복잡하기 때문에 전체 코드에 대한 확실한 답을 줄 시간이 없었습니다. 그래서 그 대신 난 그냥 당신에게 TL 줄거야,없는 것보다는 낫다 DR 버전을 나는 희망 :


내 창자가 나는 UI가보다는 다운로드하려는 시도를 나타내는 조치를 파견해야한다고 하더군요 진정한 보장. 예 : ATTEMPT_DOWNLOAD. 서사시는이 동작을 듣고 현재 다운로드 수가 최대치를 초과하는지 확인하고, 최대 다운로드 수를 초과하면 다운로드를 시작하지 않고 대기열에 넣기위한 동작을 실행합니다.

감속기에는 대기중인 사람들의 다운로드 ID 및 다운로드 ID가 저장됩니다. 예 : 당신이 활동의 ​​모두 유지 트랙 사용하는 것이

{ active: ['123', '456', ...etc], queued: ['789'] } 

은/ queued.length

는 다운로드가 어떤 대기열이 있는지 확인 할 곳 서사시을 완료하면, 그 active.length의 수를 알 수 있도록 특별히뿐만 아니라 대기 다운로드하고 '예'인 경우 하나를 dequeue하십시오. 당신이하는 일은 대체로 개인적인 취향입니다. 예 : 서사시가 DEQUEUE_DOWNLOAD 또는 무엇이든 내뿜는다면.

취소 조치가 전달되면 귀하의 감속비가 activequeued을보고 거기에 존재하는 경우 ID를 제거해야합니다. 실제로 활성 상태이고 대기열에있는 것이 아니라면 다운로드를 처리하는 서사시는 취소 작업을 수신하고 멈추고 위와 동일한 대기열에서 제외 확인을 수행합니다.


조금 손으로 물결 모양이지만, 큰 테이크 아웃이 있습니다 : 그것은 시도하기 전에 그것을 볼 수 있지만

  • 귀하의 UI 구성 요소, 방법을 알고 안이나 물건이 대기 할 때 REDUX 상태를보고하여 사후
  • 이주의 여러 곳에서 다운로드의 상태를 복제 할 수 없습니다 (예 : "다운로드가 대기"또는 어떤 표시합니다). 예 : 활성 상태 인 경우, 만은 감속기 후에 실행
  • 서사시 ​​말한다 상점에서 진리의 하나의 소스를 가지고, 당신의 이점에 이것을 사용합니다.
  • 아마 작업이 그런 식으로 대기 또는 물건에 대해 아무것도 모른 채, 사실 다운로드 요청을 수신하고 그것을 수행하는 것입니다 만의 서사시가 될 것입니다. 이 서사시는 여러 다른 서사시에 의해 재사용됩니다. 함수로 직접 호출하거나 실제와 같은 동작을 수행하여 START_DOWNLOAD

비즈니스 논리가 어디에 있어야하는지 명확하지 않습니다. 예 : 감속기는 대부분의 getter/setter를해야하거나 더 많은 의견을 고집하는 논리를 가지고 의사 결정을해야합니까? 이 경우에는 많은 규칙이 없습니다. 일관성있게하려고하십시오.

은 BTW이 내 창자에서 완전히이다. 나는 이것이 실제로 좋은 해결책이 아니라는 사실을 발견했을 수도 있습니다. 그냥 내 초기 생각을 내놔!