Сообщения шины событий в Vue.js - это мощная возможность, которая позволяет взаимодействовать не родительским / дочерним компонентам. Обычно это идеальное решение, когда требуется односторонняя связь.
Недавно мне понадобилась такая же возможность отправить сообщение слушающему $on()
и после некоторой работы отправить результат обратно $emit()
вызывающему, но Vue.js не имеет встроенного способа сделать это. В моем случае у меня была база данных в основном процессе, к которой мне нужно было контролировать доступ.
В этом примере используется база данных Lovefield.
Используя Promises, можно создать желаемый функционал.
Main.js
var db = new Database() var dbReady = false EventBus.$on(‘dbDoAction’, (data, resolve, reject) => { if (dbReady) { db.handleAction(data, resolve, reject) } else { // add job to a queue } }) db.init().then(() => { dbReady = true })
Users.js
let prms = new Promise((resolve, reject) => { var data = { action: ‘getUser’, id: 10 } EventBus.$emit(‘doAction’, data, resolve, reject) }) prms.then((res) => { // use res }).catch((err) => { // handle error })
Database.js
class Database { constructor () { this.db = null this.databases = { users: null } } init () { var s = schemas.getSchemas() return s.connect().then((db) => { this.db = db this.databases.users = db.getSchema().table(‘users’) }) } doAction (data, resolve, reject) { if (typeof this[data.action] !== ‘function’) { reject(`Database class function does not exist: ${data.action}`) } else { this[data.action](data).then((res) => { resolve(res) }).catch((err) => { reject(err) }) } } getUser (data) { return this.db.select() .from(this.databases.users) .where(this.databases.users.id.eq(data.id)) .exec() } }
Очевидно, вы захотите добавить систему очередей для действий в случае, если база данных еще не готова. Схемы определяются так же, как на примерах Лавфилда.
Заключение
Хотя Vue.js не имеет встроенной поддержки для отправки сообщений обратно эмиттерам шины событий, добавить функциональность с помощью Promises просто. Или, если хотите, вы также можете реализовать дизайн обратного вызова.
Если вы нашли этот пост полезным, загляните на мой личный сайт, где я продолжу писать на https://jsgv.io