Сообщения шины событий в 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