javascript - 如何序列化/反序列化 JS observable?
问题描述
如果我有一个可观察的流,使用RxJS或类似的,像这样(大理石图):
----1------2------3--4---|
如何将其序列化为NDJSON之类的格式,以便将其保存在数据库中?保存后,如何将其重构为可观察对象?
对于上下文,我想在 DOM 中捕获用户操作流(如鼠标拖动等),然后在稍后与用户最初执行的操作完全相同的时间重播它们。
解决方案
如果时间很重要,您可能希望将时间值与事件本身一起存储。
小POC:
import { fromEvent, Observable, of, timer } from "rxjs";
import {
map,
tap,
mergeMap,
concatMap,
takeUntil,
mapTo
} from "rxjs/operators";
let latestCache: Array<{ time: number; event: MouseEvent }>;
fromEvent(document.getElementById("start-cache"), "click")
.pipe(
concatMap(() => {
const source = fromEvent(window, "mousemove").pipe(
tap((x: MouseEvent) => console.log(x.clientX, x.clientY)),
takeUntil(timer(1000)),
store( newCache => (latestCache = newCache))
);
function store(
onCacheCreated: (
cache: Array<{ time: number; event: MouseEvent }>
) => void
) {
const cache = [];
let lastTime = Date.now();
return tap({
next: (x: MouseEvent) => {
cache.push({ time: Date.now() - lastTime, event: x });
lastTime = Date.now();
},
complete: () => onCacheCreated(cache)
});
}
return source;
})
)
.subscribe();
fromEvent(document.getElementById("replay-cache"), "click")
.pipe(
concatMap(() => {
if (!latestCache) {
console.error("no cache yet");
}
return of(...latestCache).pipe(
concatMap(x => timer(x.time).pipe(mapTo(x.event))),
tap((x: MouseEvent) => console.log(x.clientX, x.clientY))
);
})
)
.subscribe();
<h1>RxJS playground</h1>
<p>Open the console below to see results</p>
<button id="start-cache">Start Cache </button>
<button id="replay-cache">Replay Cache </button>
https://stackblitz.com/edit/rxjs-vxwurq?file=index.ts
从这里开始,您可以使用 onCacheCreated 函数随心所欲地存储数组。
推荐阅读
- laravel - Laravel 查询生成器快速 JSON 连接不为空
- android - 从数据库中检索图像列表并使用 ListView 显示它们?
- java - 处理来自 rabbitmq 错误队列的消息
- google-cloud-platform - 如何获取一个巨大的谷歌云存储桶中所有对象的报告?
- sql-server - 连接到 Azure SQL 数据库时出错。信号量超时期限已过。(Microsoft SQL Server,错误:121)
- postman - 如何通过邮递员的测试访问路径参数?
- android - setSupportActionBar 不适用于 YouTubeBaseActivity
- python - Google oauth - 获取用户电子邮件
- c - 组合宏会产生错误
- php - htaccess 正则表达式忽略 url 中的查询字符串