2014-05-13 1 views
29

Flux 아키텍처의 Facebook 토크에서 Jing은 at 12:17에서 현재 작업이 상점에서 완전히 처리 될 때까지는 아무 작업도 보낼 수 없다고 말합니다.Flux로 비동기 저장 작업을 어떻게 관리합니까?

https://img.youtube.com/vi/nYkdrAPrdcw/0.jpg

여기 발송자는 케스 케이 딩 효과가 없다는 것을 강제 주요 작품이다; 작업이 상점에 들어가면 상점이 처리를 완전히 마칠 때까지 다른 작업을 넣을 수 없습니다.

제 질문은 상점에서 시작될 수있는 장기 실행 비동기 작업 (예 : Ajax 요청 또는 다른 외부 비동기 API 처리)을 어떻게 적절하게 처리 할 것인가입니다. 액션 디스패치 (예 : Ajax 요청의 결과로 약속을 해결하기 위해 대기 중)를 완료하면 사용자가 UI에서 생성 한 액션이 전달되지 않을 수 있습니다.

답변

30

Ajax 등에 의존하는 비동기 액션은 모든 가입자에게 조치가 전달되지 않도록 차단해서는 안됩니다.

당신은 호출되는 것을 TodoMVC 예에서 TODO_UPDATE_TEXT 및처럼 사용자 동작에 대한 별도의 조치를해야 할 때의 새 복사본을 포함하는 서버가 반환, TODO_UPDATE_TEXT_COMPLETED 같은 (또는 TODO_UPDATE_COMPLETED 같은보다 일반적인 어쩌면 뭔가 최신 속성).

사용자가 변경 효과를 즉시 보여주기 위해 낙관적 인 업데이트를 수행하려는 경우 즉시 사용자 작업에 대한 응답으로 저장소를 업데이트 할 수 있습니다 (서버가 신뢰할 수있는 데이터를 반환 할 때 다시 한 번) . 서버에서 대기하려는 경우 서버가 트리거 한 작업에 대한 응답으로 만 저장소를 업데이트 할 수 있습니다.

+3

업데이트가 실패하고 서버가 표시하려는 오류 메시지를 반환한다고 가정합니다. TODO_UPDATE_FAILED 핸들러에서 수행 할 작업에 오류 메시지를 저장 하시겠습니까? – scttnlsn

+3

@scttnlsn 오류 메시지를 TodoStore에 저장해야하는지 스스로 물어볼 필요가 있습니다. 그렇지 않은 경우 제안 사항으로, 오류 메시지를 처리하는 구성 요소 (예 : 경고 메시지 구성 요소)가 사용하는 오류 메시지 용 별도의 데이터 저장소를 만들어야합니다. – Spoike

+0

여러 작업으로 하나의 작업을 깨는 것은 일을 망칠 수 있습니다. 두 개 이상의 작업이 서로 얽히게되면이를 피하는 것이 가장 좋습니다. –

2

Sophie가 비동기 데이터를 처리 할 때 this fluxxor example에서 설명한 것에 대한 구현을 참조하십시오. 부정적인 점은이 접근법에 따르면 각 사용자 상호 작용에는 세 가지 동작 (트리거, 성공 및 실패)이 필요하지만 모든 사용자 상호 작용에 이러한 낙관적 인 접근 방식이 필요하지는 않습니다.

중요한 부분은 액션에 있습니다

loadBuzz: function() { 
    this.dispatch(constants.LOAD_BUZZ); 

    BuzzwordClient.load(function(words) { 
    this.dispatch(constants.LOAD_BUZZ_SUCCESS, {words: words}); 
    }.bind(this), function(error) { 
    this.dispatch(constants.LOAD_BUZZ_FAIL, {error: error}); 
    }.bind(this)); 
    }, 

BinaryMuse (fluxxor 창조자)는 LOAD_BUZZ 조치를 전달하고 성공 비동기 요청을 트리거 및 기능을 실패 여기서 성공을 전달하거나 조치를 실패합니다. 상점은 낙관적 인 업데이트를 위해 LOAD_BUZZ 작업을 청취하거나 svg 로딩 아이콘을 표시 한 다음 성공 또는 오류의 최종 알림 (스토어에 BUZZWORD 저장)에 대한 성공 및 오류 동작을 수신 할 수 있습니다.

onLoadBuzz: function() { 
    this.loading = true; 
    this.emit("change"); 
}, 

onLoadBuzzSuccess: function(payload) { 
    this.loading = false; 
    this.error = null; 

    this.words = payload.words.reduce(function(acc, word) { 
    var clientId = _.uniqueId(); 
    acc[clientId] = {id: clientId, word: word, status: "OK"}; 
    return acc; 
    }, {}); 
    this.emit("change"); 
}, 

나는이 더 서버에 동기 요청 및 영향을받는 페이지의 응답처럼 때문에 아약스 요청이 파견되는 작용을 차단해서는 안 소피처럼 생각합니다.

관련 문제