actions
в Vuex являются асинхронными. Единственный способ позволить вызывающей функции (инициатору действия) знать, что действие завершено, - это вернуть обещание и разрешить его позже.
Вот пример: myAction
возвращает 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);
})
})
}
}
Теперь, когда ваш компонент Вью инициирует myAction
, он получит этот объект Promise и может знать, удалось ли это или нет. Ниже приведен пример кода для компонента Вю:
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
, так как actions
ручка эта часть.
Редактировать: Мои взгляды на цикл Vuex из однонаправленного потока данных:
Если доступ к данным как this.$store.state["your data key"]
в ваших компонентах, то поток данных является однонаправленным.
Обетование от действия только для того, чтобы компонент знал, что действие завершено.
Компонент может использовать данные из функции разрешения обещаний в приведенном выше примере (не однонаправленный, поэтому не рекомендуется), либо непосредственно из $store.state["your data key"]
, который является однонаправленным и следует за жизненным циклом данных vuex.
Вышеупомянутый абзац предполагает, что ваш мутатор использует Vue.set(state, "your data key", http_data)
, как только HTTP-запрос будет завершен в вашем действии.
«Как вы можете видеть выше, очень полезно, чтобы действия возвращали обещание. В противном случае инициатор действия не может знать, что происходит, и когда все достаточно стабильно, чтобы что-то показывать в пользовательском интерфейсе». ИМО, этого не хватает в Vuex.Инициатор действия не должен * знать, что происходит. Действие должно мутировать состояние, когда данные возвращаются из асинхронного события, и компонент должен реагировать на это изменение этапа, основанное на состоянии хранилища Vuex, а не на Promise. – ceejayoz
@ceejayoz Согласовано, государство должно быть единственным источником истины для всех объектов данных. Но обещание - это единственный способ связаться с инициатором акции. Например, если вы хотите показать кнопку «Попробовать еще раз» после отказа HTTP, эта информация не может войти в состояние, но может быть передана только через «Promise.reject()». – Mani
Это легко обрабатывается в магазине Vuex. Само действие может запускать «failed» мутатор, который устанавливает 'state.foo.failed = true', который компонент может обрабатывать. Нет необходимости в том, чтобы обещание было передано компоненту для этого, и в качестве бонуса все, что угодно * else *, которое хочет реагировать на один и тот же отказ, может сделать это и в магазине. – ceejayoz