Programing

Vuex 작업에서 약속 반환

c10106 2022. 4. 5. 21:04
반응형

Vuex 작업에서 약속 반환

나는 최근에 물건을 JQ에서 VueJS라는 좀 더 구조화된 프레임워크로 옮기기 시작했는데, 너무 좋아!

개념적으로, Vuex는 나에게 약간 패러다임의 변화였지만, 나는 지금 무슨 일이 일어나고 있는지 알고 있다고 확신해, 그리고 완전히 이해했어!그러나 대부분 구현의 관점에서 약간의 회색 영역이 존재한다.

내가 느끼는 이 것은 설계상으로는 좋지만 단방향 데이터 흐름의 Vuex 사이클과 모순되는지는 모르겠다.

기본적으로 행동에서 약속(같은) 대상을 반환하는 것이 좋은 관행으로 여겨지는가?나는 이것들을 비동기 포장지로 취급하는데, 실패 상태 등이 있고, 그래서 약속을 되돌리기에 좋은 것 같다.정반대로 돌연변이는 사물을 변화시킬 뿐이고, 가게/모듈 내의 순수한 구조물이다.

actionsVuex에서는 비동기적이다.호출 기능(행동 개시자)이 동작이 완료되었음을 알게 하는 유일한 방법은 약속을 반환하고 나중에 해결하는 것이다.

예를 들면 다음과 같다.myActiona를 반환하다Promise, http 호출 후 결정 또는 거부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")
        })
    }
}

위에서 볼 수 있듯이, 그것은 매우 유익하다.actionsa를 반환하다Promise. 그렇지 않으면 작업 개시자가 사용자 인터페이스에 무언가를 표시할 수 있을 정도로 상황이 안정적일 때 어떤 일이 일어나고 있는지 알 수 있는 방법이 없다.

그리고 다음에 대한 마지막 메모mutators- 당신이 올바르게 지적했듯이, 그것들은 동기식이다.그들은 그 안에서 물건을 바꾼다.state, 그리고 보통 에서 불려진다.actions섞을 필요가 없다.Promises와 함께mutators처럼actions그 부분을 다루다

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

다음과 같은 데이터에 액세스하는 경우this.$store.state["your data key"]구성 요소에서 데이터 흐름은 단조로워진다.

행동에서 오는 약속은 오직 구성 요소에게 행동이 완료되었음을 알리는 것이다.

구성 요소는 위의 예에서 약속 해결 기능(단방향은 아니므로 권장되지 않음)으로부터 직접 데이터를 가져올 수 있다.$store.state["your data key"]이는 단방향이며 vuex 데이터 라이프사이클을 따른다.

위의 단락은 당신의 돌연변이가Vue.set(state, "your data key", http_data)동작에서 http 호출이 완료되면.

약속을 만들 필요가 없다는 폐쇄적인 주제에 대한 정보를 얻기 위해, 공리는 스스로 하나를 돌려준다.

참조: 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) => {
          commit('logUserIn', response.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
        })
    }

비동기 대기 상태의 다른 예

    async getUser({ commit }) {
        try {
            const currentUser = await axios.get('/user/current')
            commit('setUser', currentUser)
            return currentUser
        } catch (err) {
            commit('setUser', null)
            throw 'Unable to fetch current user'
        }
    },

행동들

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: 필요한 경우에만 사용자의 약속을 반환하되, DREATE는 동일한 작업을 연결하십시오.

오랫동안 나는 또한 반환 작업이 단방향 데이터 흐름의 Vuex 사이클과 모순된다.

그러나, 당신의 행동에서 약속을 되돌리는 것이 "필요한" 경우가 있다.

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

멍청한 예

사용자가 네비바 및 /profile 페이지(내비바 포함)에서 사용자 이름을 편집할 수 있는 페이지.둘 다 비동기적인 "사용자 이름 변경" 작업을 트리거한다.약속에 실패하면 사용자가 사용자 이름을 변경하려는 구성 요소의 오류만 페이지에 표시되어야 한다.

물론 바보 같은 예지만, 나는 두 가지 다른 행동에서 코드를 복제하고 같은 통화를 하지 않고 이 문제를 해결할 방법을 찾을 수 없다고 본다.

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);
    });
  },
}

홈뷰

<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

반응형