dueljs icon indicating copy to clipboard operation
dueljs copied to clipboard

Не работает emit событий отправленных друг за другом

Open NeXTs opened this issue 8 years ago • 1 comments

Привет

На днях заметил что не работает .emit событий отправленных друг за другом.

Пример

channel.emit('demo_trigger', 'ya1', duel.getWindowID())
channel.emit('demo_trigger', 'ya2', duel.getWindowID())
channel.emit('demo_trigger', 'ya3', duel.getWindowID())

Чтоб воспроизвести, вставь содержимое этого в свой public/index.html. Открой две вкладки и нажми кнопку эмита. Во второй вкладке в консоли вместо трех разных сообщений будет два "ya3". Остальные теряются.

Перебором определил что более-менее без потерь (и то не в 100% случаях) сообщения начинают доставляться только с 750мс задержкой между вызовами.

channel.emit('demo_trigger', 'ya1', duel.getWindowID())
setTimeout(function() {
    channel.emit('demo_trigger', 'ya2', duel.getWindowID())
    setTimeout(function() {
        channel.emit('demo_trigger', 'ya3', duel.getWindowID())
    }, 750)
}, 750)

У себя в проекте я использую dueljs для синхронизации redux стора между табами передавая экшны с мастера слейвам. Из-за этих потерь начались проблемы ) В качестве костыля создал буффер и _.throttle на 750мс, стало чуть лучше, но все равно бывают потери. Хотелось бы решения на уровне библиотеки :)

import throttle from 'lodash/throttle'
import each from 'lodash/each'
import duel from 'dueljs'

let syncStore = duel.channel('syncStoreChannel')

const syncState = (store) => {
    syncStore.on('sync', function(actions) {
        each(actions, store.dispatch)
    })
}

let actionsBuffer = []
const flushActionsBuffer = throttle(() => {
    syncStore.emit('sync', actionsBuffer)
    actionsBuffer.length = 0
}, 750)

export const createSyncMiddleware = store => next => action => {
    if(window.isMaster()) {
        actionsBuffer.push(action)
        flushActionsBuffer()
    }
    next(action)
}

export default syncState

NeXTs avatar Jan 19 '17 00:01 NeXTs

Спасибо за репорт, обязательно поправлю. Пока как временное решение, можешь попробовать передавать группу событий вместо событий по одиночке.

studentIvan avatar Jan 19 '17 13:01 studentIvan