Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 浏览器选项卡之间的重复通信产生乒乓球效果(多路通信)_Javascript_Redux_Local Storage - Fatal编程技术网

Javascript 浏览器选项卡之间的重复通信产生乒乓球效果(多路通信)

Javascript 浏览器选项卡之间的重复通信产生乒乓球效果(多路通信),javascript,redux,local-storage,Javascript,Redux,Local Storage,我看到了很多关于如何使用Redux/JavaScript和localstorage在选项卡之间通信/共享数据的解决方案。比如: import { applyMiddleware, createStore } from "redux"; import logger from "redux-logger"; import thunk from "redux-thunk"; import promise from "redux-promise-middleware"; import reducer

我看到了很多关于如何使用Redux/JavaScript和localstorage在选项卡之间通信/共享数据的解决方案。比如:

import { applyMiddleware, createStore } from "redux";
import logger from "redux-logger";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";

import reducer from "./reducers";
import {sourceId} from "./utils/helper";

const storageKey = 'redux-local-tab-sync';

function wrapAction(action) {
  return {
    action,
    sourceId,
    time: Date.now()
  }
}

function storageMiddleware() {
  return () => next => action => {
    const wrappedAction = wrapAction(action);

    localStorage.setItem(storageKey, JSON.stringify(wrappedAction));

    next(action);
  }
}

export function createStorageListener(store) {
  return () => {
    const wrappedAction = JSON.parse(localStorage.getItem(storageKey));

    if (wrappedAction.sourceId !== sourceId) {
      console.log(wrappedAction.action)
      store.dispatch(wrappedAction.action);
    }
  }
}

const middleware = applyMiddleware(promise(), thunk, storageMiddleware(), logger());
const store = createStore(reducer, middleware);

window.addEventListener('storage', createStorageListener(store));

export default store;
或和

然而,我发现所有的解决方案都有一个小问题。它们产生了乒乓球的效果。因此,当一个选项卡存储发生更改时,将设置B选项卡存储,因为它从localstorage获取一条消息。但是,因为B选项卡存储是更改的,所以它会触发“相同的更改事件”(但带有自己的信息),该事件以前是由选项卡发送的。因此选项卡的存储将通过本地存储事件进行更改。。。一切都从一开始

是否有更好的方法来处理以下位置的信息同步:
-A可以向B[,C,D,…]发送消息;B可以向a[,C,D,…]发送消息;etc
-不产生乒乓球效果,

-防止无限地更改自己的存储。

可能以下操作会起作用,当从另一个选项卡触发时,它将创建一种特殊类型的操作:

function storageMiddleware() {
  return () => next => action => {
    if(action.type!=="from other tab"){
      const wrappedAction = wrapAction(action);
      localStorage.setItem(storageKey, JSON.stringify(wrappedAction));
    }else{
      action=action.data;
    }
    next(action);
  }
}

export function createStorageListener(store) {
  return () => {
    const wrappedAction = JSON.parse(localStorage.getItem(storageKey));

    if (wrappedAction.sourceId !== sourceId) {
      console.log(wrappedAction.action)
      store.dispatch({
        type:"from other tab",
        data:wrappedAction.action
      });
    }
  }
}

也许您可以尝试一下,广播频道是在选项卡之间进行通信的更好方式。

作为消息的一部分,设置包含“源”选项卡的属性。然后,您可以轻松地检查事件是否源自当前选项卡并忽略它。是的,我使用“sourceId”来执行此操作。但是,在相反的选项卡上,这是以同样的方式设置的,在它更新了自己的存储之后,它在那里设置了自己的“sourceId”,它会将A检测为新状态,但它是A自己的状态。实际上,我需要以某种方式防止在第
localStorage.setItem
行将接收到的事件发送/设置回localStorage。但我不知道那个事件是从哪里来的…这个图书馆太棒了。谢谢你。@anthony dandrea很高兴你喜欢它:)