IT

Vuex 작업에서 약속 반환

lottoking 2020. 8. 29. 13:20
반응형

Vuex 작업에서 약속 반환


저는 최근에 jQ에서 VueJS 인보 다 구조화 된 프레임 워크로 이전하기 시작했는데 정말 마음에 씁니다!

개념적으로 Vuex는 저에게 약간의 패러다임 전환이지만 지금은 그 모든 것이 무엇인지 완전히 이해합니다! 그러나 주로 구현 관점에서 볼 때 약간의 회색 영역이 있습니다.

이것은 디자인 상 좋지만 단방향 데이터 흐름 의 Vuex 주기모순 있고 모르겠습니다 .

기본적으로 액션에서 promise (유사 방법)를 반환하는 것이 좋은 것이? 나는 그것을 실패 상태 등의 표현 래퍼로 취급 약속을 반환하는 것처럼 보이게합니다. 뮤 테이터는 단지 사물을 변경하고 스토어 / 모듈 내의 순수한 구조입니다.


actionsVuex에서는 용어 식입니다. 호출 함수 (동작이 개시 자)가 동작이 완료되는 알 수있는 유일한 방법은 약속을 나중에 해결하는 것입니다.

예를 들면 다음과 제안을 myAction반환하고 Promisehttp를 호출하고 Promise나중에 확인 거부합니다. 모두 적으로

actions: {
    myAction(context, data) {
        return new Promise((resolve, reject) => {
            // Do something here... lets say, a http call using vue-resource
            this.$http("/api/something").then(response => {
                // http success, call the mutator and change something in state
                resolve(response);  // Let the calling function know that http is done. You may send some data back
            }, error => {
                // http failed, let the calling function know that action did not work out
                reject(error);
            })
        })
    }
}

이제 Vue 구성 요소가 시작 myAction하면이 Promise 개체를 가져와 성공 여부를 알 수 있습니다. 다음은 Vue 구성 요소의 샘플 코드입니다.

export default {
    mounted: function() {
        // This component just got created. Lets fetch some data here using an action
        this.$store.dispatch("myAction").then(response => {
            console.log("Got some data, now lets show something in this component")
        }, error => {
            console.error("Got nothing from server. Prompt user to check internet connection and try again")
        })
    }
}

위에서 볼 수 있듯이, 위해 매우 유용을합니다 actions를 반환 Promise. 어떤 일이 일어나고 있는지 그리고 사용자 인터페이스에 있는지 알 수있는 방법이 있습니다.

그리고 마지막 메모 mutators-당신이 지적했듯이 그들을 동 기적입니다. 일반적으로에서 항목을 변경 state하고 호출 actions합니다. 할 필요가 혼합 없습니다 Promises으로 mutators는 AS, actions그 부분 핸들.

편집 : 단방향 데이터 흐름의 Vuex주기에 대한 내 견해 :

this.$store.state["your data key"]구성 요소에서 와 같이 데이터에 액세스하는 경우 데이터 흐름은 단방향입니다.

작업의 약속은 구성 요소에 작업이 완료 알리는 것입니다.

구성 요소는 약속 해결 기능에서 데이터를 가져 오거나 ( $store.state["your data key"]단방향이 아니 위 권장하지 않음) 직접 단방향이고 vuex 데이터 수명주기를.

위의 단락은 Vue.set(state, "your data key", http_data)http 호출이 작업에서 완료 할 mutator 가를 사용 가정합니다 .


닫힌 주제에 대한 정보를 위해 : 약속을 만들 필요가 없습니다. axios는 약속을 스스로 반환합니다.

참조 : https://forum.vuejs.org/t/how-to-resolve-a-promise-object-in-a-vuex-action-and-redirect-to-another-route/18254/4

예 :

export const loginForm = ({commit},data) => {
        return axios.post('http://localhost:8000/api/login',data).then((response) => {
            console.log(response);
            commit('logUserIn',response.data.data);
        }).catch((error) => {
            commit('unAuthorisedUser',{
                error:error.response.data
            })
        })
};

다른 예시 :

    addEmployee({ commit, state }) {       
        return insertEmployee(state.employee).then(result => {
            commit('setEmployee', result.data);
            return result.data // resolve 
        }).catch(err => {           
            throw err.response.data // reject
        });
    },

행위

ADD_PRODUCT : (context,product) => {
  return Axios.post(uri, product).then((response) => {
    if (response.status === 'success') {  
      context.commit('SET_PRODUCT',response.data.data)
    }
    return response.data
  });
});

구성 요소

this.$store.dispatch('ADD_PRODUCT',data).then((res) => {
  if (res.status === 'success') {
    // write your success actions here....
  } else {
     // write your error actions here...
  }
})

TL : DR; 필요한 경우에만 작업에서 약속을 반환하지만 DRY 연결합니다.

오랜 시간 동안 나는 또한 그 반환 동작이 단방향 데이터 흐름의 Vuex주기와 모순된다.

그러나 당신의 행동에서 약속을 돌려주는 것이 "필요한" EDGE CASES 가 있습니다.

두 가지 다른 구성 요소에서 작업이 트리거 될 수 있고 각각 실패 사례를 다르게 처리하는 상황을 상상해보십시오. 이 경우 호출자 구성 요소를 매개 변수로 전달하여 상점에서 다른 플래그를 설정해야합니다.

멍청한 예

사용자가 navbar 및 / profile 페이지 (navbar 포함)에서 사용자 이름을 편집 할 수있는 페이지입니다. 둘 다 비동기식 인 "사용자 이름 변경"작업을 트리거합니다. 약속이 실패하면 페이지는 사용자가 사용자 이름을 변경하려는 구성 요소에만 오류를 표시해야합니다.

물론 이것은 멍청한 예이지만 코드를 복제하고 두 가지 다른 작업에서 동일한 호출을하지 않고는이 문제를 해결할 수있는 방법을 찾지 못했습니다.


actions.js

const axios = require('axios');
const types = require('./types');

export const actions = {
  GET_CONTENT({commit}){
    axios.get(`${URL}`)
      .then(doc =>{
        const content = doc.data;
        commit(types.SET_CONTENT , content);
        setTimeout(() =>{
          commit(types.IS_LOADING , false);
        } , 1000);
      }).catch(err =>{
        console.log(err);
    });
  },
}

home.vue

<script>
  import {value , onCreated} from "vue-function-api";
  import {useState, useStore} from "@u3u/vue-hooks";

  export default {
    name: 'home',

    setup(){
      const store = useStore();
      const state = {
        ...useState(["content" , "isLoading"])
      };
      onCreated(() =>{
        store.value.dispatch("GET_CONTENT" );
      });

      return{
        ...state,
      }
    }
  };
</script>

참고 URL : https://stackoverflow.com/questions/40165766/returning-promises-from-vuex-actions

반응형