Devolver promesas de Vuex acciones


Recientemente comencé a migrar cosas de jQ a un marco más estructurado siendo VueJS, ¡y me encanta!

Conceptualmente, Vuex ha sido un poco de un cambio de paradigma para mí, pero estoy seguro de que sé lo que es todo acerca de ahora, y totalmente conseguirlo! Sin embargo, existen algunas pequeñas zonas grises, sobre todo desde el punto de vista de la aplicación.

Este me parece bueno por diseño, pero no sé si contradice el ciclo de Vuex de flujo de datos unidireccional.

, Básicamente, es considerado una buena práctica para devolver una promesa(-como) objeto de una acción? Los trato como envoltorios asíncronos, con estados de fracaso y similares, por lo que parece una buena opción para devolver una promesa. Por el contrario, los mutadores solo cambian las cosas, y son las estructuras puras dentro de un almacén/módulo.

Author: Daniel Park, 2016-10-21

2 answers

actions en Vuex son asíncronos. La única manera de permitir que la función que llama (iniciador de la acción) sepa que una acción está completa es devolviendo una Promesa y resolviéndola más tarde.

Aquí hay un ejemplo: myAction devuelve un Promise, hace una llamada http y resuelve o rechaza el Promise más tarde-todo asincrónicamente

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

Ahora, cuando su componente Vue inicie myAction, obtendrá este objeto Promise y podrá saber si tuvo éxito o no. Aquí hay un código de ejemplo para el componente 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")
        })
    }
}

Como puedes ver arriba, es altamente beneficioso para actions devolver un Promise. De lo contrario, no hay forma de que el iniciador de acciones sepa lo que está sucediendo y cuándo las cosas son lo suficientemente estables como para mostrar algo en la interfaz de usuario.

Y una última nota con respecto a mutators - como usted correctamente señaló, son sincrónicos. Cambian cosas en el state, y generalmente se llaman desde actions. No hay necesidad de mezclar Promises con mutators, ya que el actions maneja eso parte.

Editar: Mis puntos de vista sobre el ciclo Vuex de flujo de datos unidireccional:

Si accede a datos como this.$store.state["your data key"] en sus componentes, entonces el flujo de datos es unidireccional.

La promesa de la acción es solo hacerle saber al componente que la acción está completa.

El componente puede tomar datos de la función promise resolve en el ejemplo anterior (no unidireccional, por lo tanto no se recomienda), o directamente de $store.state["your data key"] que es unidireccional y sigue el ciclo de vida de los datos vuex.

El párrafo anterior asume que su mutador usa Vue.set(state, "your data key", http_data), una vez que se completa la llamada http en su acción.

 122
Author: Mani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-15 03:14:14

Solo para una información sobre un tema cerrado: no tienes que crear una promesa, axios devuelve una:

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

Ejemplo:

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
            })
        })
};
 2
Author: Anoop.P.A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-03 08:38:32