使用时初始化缓存

2024-02-23

假设我有以下事件:

  • 做一点事
  • 取东西
  • 获取成功的东西

DoSomething做一些需要一些缓存数据的事情。当我触发事件时,我想查看缓存并对其执行某些操作(如果存在)。如果没有,那么我想获取它,等待它进入缓存,然后重试。

我想出了以下解决方案,但感觉就像我在滥用map操作员。有没有更合适的操作符来观察流并抛出错误或达到重试的效果?

const DO_SOMETHING = 'DO_SOMETHING';
const FETCH_SOMETHING = 'FETCH_SOMETHING';
const FETCH_SOMETHING_SUCCESSFUL = 'FETCH_SOMETHING_SUCCESSFUL';

const events = new Rx.Subject();
const cache = new Rx.BehaviorSubject(null);

// the magic sauce
const cacheInitializer = cache
// is there a better way than this?
.map(x => {
  if (!x) { throw 'empty'; }
  return x;
})
.retryWhen(x => {
  console.log('Cache is empty');
  events.next(FETCH_SOMETHING);
  return events.filter(x => x === FETCH_SOMETHING_SUCCESSFUL)
    .first();
});

// fake getting the data
events.filter(x => x === FETCH_SOMETHING)
.do(() => { console.log('Fetching data'); })
.delay(1000)
.subscribe(x => {
  console.log('Data fetched and put into cache');
  cache.next({ data: 1 });
  events.next(FETCH_SOMETHING_SUCCESSFUL);
});

// handle doing something
events.filter(x => x === DO_SOMETHING)
.do(() => { console.log('Check the cache'); })
.switchMapTo(cacheInitializer)
.subscribe(x => {
  	console.log('Do something', x);
});

events.next(DO_SOMETHING);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>

Context:我正在使用 ngrx 和效果。FETCH_SOMETHING会触发另一种效果FETCH_SOMETHING_SUCCESSFUL将表明效果已成功完成。在本例中我的缓存是 ngrx。我认为我不想在 API 层中缓存,因为这仍然会导致我从缓存的响应中更新状态,而不是仅仅依赖于状态中的数据。


你想要一个简单的shareReplay,但您需要 rxjs 5.5.0 或更高版本,因为有一个错误已修复。

const cached$ = request$.shareReplay(1);

这将在第一次订阅时触发请求,但后续订阅将使用缓存的值。

错误将传递给订阅者,然后销毁内部主题,以便错误本身不会被缓存。这使得可观察的可重试。因此,您可以附加任何您想要的重试逻辑(例如重试直到成功)。

最后,如果 refCount 在某个时刻变为 0,缓存也会持续存在。

shareReplay还需要第二个参数,很像ReplaySubject构造函数,定义保留缓存的时间窗口。

// Faked request which sometimes errors
const request$ = Rx.Observable
  .defer(() => Rx.Observable.of(Math.random()))
  .do(() => console.log('API called'))
  .map(val => {
    if (val <= 0.3) {
      console.log('API error');
      throw val;
    } else {
      return val;
    }
  })
  .delay(250);

const cached$ = request$.shareReplay(1);

Rx.Observable.timer(0, 1000)
  .take(5)
  .switchMap(() => cached$.retry(5))
  .subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用时初始化缓存 的相关文章

  • 添加 Javascript 按钮来更改 iframe 的内容

    我正在尝试创建此页面 其中有一个 Iframe 并且我想添加一个按钮来显示 iframe 中的下一页 以及一个按钮来显示 iframe 中的上一页 我总共有 4 个页面要在名为 1 html 2 html 3 html 4 html 的 i
  • Javascript 闭包与 PHP 闭包,有什么区别?

    JS 中的闭包和 PHP 中的闭包有什么区别 它们的工作方式几乎相同吗 在 PHP 中编写闭包时有什么需要注意的注意事项吗 一个区别是两者如何处理存储执行匿名函数的上下文 JavaScript var a 1 var f function
  • 如何在chartjs中绘制多个时间序列,其中每个时间序列都有不同的时间

    例如 我有两个时间序列 s1 2017 01 06 18 39 30 100 2017 01 07 18 39 28 101 and s2 2017 01 07 18 00 00 90 2017 01 08 18 00 00 105 我想在
  • Google 地图上的自定义路线/路径/道路

    我需要能够使用 V2 或 V3 最好是 3 创建在某种意义上忽略建筑物的路径 我试图创建一个 kml 文件来自己绘制所有路径 然后找到某种方法根据需要打开 关闭它们 例如 用户想要从 A 点前往 B 点 这些点之间有许多建筑物 用户可以实际
  • 从平面数组创建嵌套对象

    我目前有一个对象数组 我正在尝试将其重塑为嵌套对象ID作为对象键 并将其作为目标ID与parentid 如果不是 0 我尝试了几种方法 但我很挣扎 主要绊脚石for me是超过一两层深度的任何东西 理想情况下 我需要它是动态的 这样它就可以
  • 访问 .js 文件中的 Nuxt 插件

    假设我有一个脚本文件 foo js function doStuff how to access store and other plugins here export default doStuff 如果不将调用组件作为参数传递 我如何访
  • 将 Javascript 正则表达式转换为 PHP

    我知道这个问题已经被问了大约十几次 但是从技术上讲 这个问题并不是一个骗局 如果您愿意 请检查其他问题 基本上 我有一个 Javascript 正则表达式来检查用于前端验证的电子邮件地址 并且我使用 CodeIgniter 在后端进行双重检
  • HTML:您可以隐藏/忽略浏览器查找中的文本元素 (CTRL+F)

    我有一个具有相当复杂的 UI 的 Web 应用程序 并且屏幕的一部分保留用于内容 如果可能的话 我想这样做 以便当用户使用浏览器的内置文本搜索 CTRL F 时 UI 中的任何文本都将被忽略 并且仅搜索实际内容 这可行吗 CSS 和 Jav
  • 基于 json 文件动态显示选择、复选框、日期选择器等

    对我之前的问题的补充 我根据 json 文件动态显示输入字段 现在我想根据它们的组显示选择项 复选框和日期选择器 我如何解决这个问题 我需要将这些元素推入computeJSON 但写入例如选择options item selection不管
  • 如何在 Angular 模板中嵌入 GitHub gist?

    角度忽略script其模板中包含标签 但加载 GitHub gist 需要它们 执行此操作的最佳做 法是什么 使用iframe 创造script动态标记 或者是其他东西 一种方法是创建一个iframe with script里面并在你希望你
  • ES6 生成器——它们真的是 async/await 的替代品吗?

    评论区的帖子之一this http blogs msdn com b typescript archive 2014 10 22 typescript and the road to 2 0 aspx打字稿博客文章说 如果我必须等到 2 0
  • JavaScript 中的凯撒密码

    我正在尝试编写一个程序来解决javascript中的以下问题 写在本段下面 我不知道为什么我的代码不起作用 有人可以帮助我吗 我是 JavaScript 新手 这是一个免费的代码训练营问题 现代常见的用法是 ROT13 密码 其中字母的值移
  • 根据复选框显示/隐藏输入字段[重复]

    这个问题在这里已经有答案了 如果单击该复选框 它将显示一个输入字段 到目前为止它正在工作 但如果未选中该复选框 它应该隐藏它 我该怎么做 div class checkbox div
  • AngularJS 中的嵌套模块

    我有 2 个不同的 AngularJs 模块 一个 widgetContainer 和一个 widget 小部件可以显示为独立的应用程序 也可以包含在小部件容器中 一个 widgetContainer 包含 0 N 个 widget 如果我
  • 用空字符串替换状态:Javascript

    我有这个网址 website com con blog true 我在 javascript 中所做的是 if getURLparams blog RandomFunction change the url window history r
  • Kotlin JavaScript 到 TypeScript 定义文件

    我已经找到了ts2kt 库 https github com Kotlin ts2kt这将从任意位置创建 Kotlin 头文件 d ts文件 但是 我想朝相反的方向走 我想构建一个可以编译为 JavaScript 的 Kotlin 库 但我
  • “x modulo y”的结果是什么?

    引用 ECMAScript 规范第 5 2 节 符号 x modulo y y 必须是有限且非零 计算 值 k 与 y 具有相同的符号 或零 使得 abs k 因此 如果 y 为正 则 x modulo y 的结果 k 为正 无论 x 的符
  • 如何在画布中旋转图表同时保持数字垂直?

    我正在尝试围绕其中心旋转画布中的图表 同时保持字母直立 我正在尝试使用 ctx rotate 但它使用画布的左侧作为中心来旋转整个图表 以下链接提供了视觉效果 我希望它看起来像绿色 而不是红色 就像我的代码当前所做的那样 视觉解释 http
  • 如何始终将焦点保持在画布上?

    我一直在这个论坛寻找解决方案 但尚未找到 无论我在页面上的哪个位置单击 我都需要始终将焦点放在画布元素上 我有几个按钮 在每个 onclick 事件中我写 document getElementById canvas focus 这确实有效
  • 在哪里放置资源特定逻辑

    您能帮我考虑在 AngularJS 中将资源 服务 特定的业务逻辑放置在哪里吗 我觉得在我的资源上创建一些类似模型的抽象应该很棒 但我不确定如何做 API调用 gt GET customers 1 lt first name John la

随机推荐

  • 生成随机确定性有限自动机的算法是什么?

    DFA 必须具有以下四个属性 DFA 有 N 个节点 每个节点有 2 个传出转换 每个节点都可以从其他每个节点访问 从所有可能性中以完全一致的随机性选择 DFA 这是我到目前为止所拥有的 从 N 个节点的集合开始 选择一个尚未选择的节点 将
  • 使用委托和 Lambda 的奇怪行为

    作为在我正在开发的库中引入惰性格式化评估的一种方法 我定义了委托 public delegate string MessageFormatterDelegate string message params object arguments
  • 什么是Android UiThread(UI线程)

    有人可以向我解释一下 UI 线程到底是什么吗 在developer android com上它提到了runOnUiThread函数 公共最终无效runOnUiThread 可运行操作 从以下版本开始 API 级别 1 在 UI 线程上运行指
  • 如何让 NHibernate 停止使用 nvarchar(4000) 来插入参数字符串?

    我需要优化由域实体上的保存 插入查询 生成的查询 我已经使用 Fluent NHibernate 配置了 NHibernate 以下是 NHibernate 在插入用户对投票的响应期间生成的查询 exec sp executesql N I
  • 简洁表达数学公式的语法建议

    我正在 C 中开发功能域特定的嵌入式语言 以尽可能简洁 准确地将公式转换为工作代码 我在评论中发布了一个原型 大约有两百行长 现在我的语言看起来像这样 嗯 实际上看起来像这样 implies two nested loops j 0 N i
  • 如何阻止 GD2 在调整图像大小时洗掉颜色?

    我使用 CodeIgniter 1 7 开发了一个照片共享社区网站 成员上传的照片会自动调整为多种格式的大小 为此我使用 CodeIgniter Image Manipulation 类 该类内置于框架中 基本上是多个图像处理库的包装器 例
  • 如何在Android地图上的另一个图像中显示图像?

    我想在地图上的另一个图像中显示图像 like 这里红色的图像是不同的图像 而黑色的偶像图像是不同的 public Bitmap mergeBitmaps Bitmap manBitmap try Bitmap markerBitmap Bi
  • cakephp 3 显示没有时间的日期

    CakePHP 3 我有一个数据库字段 它是日期 不是日期时间也不是时间戳 当我显示 echo contact gt date 它会显示类似的内容2014 01 06 0 00 如何隐藏小时和分钟 I tried print this gt
  • Debian 9 + PHP7.0-FPM + NGINX 1.10.3-1 path_info 问题

    我正在使用 DigitalOcean Debian 9 PHP 7 0 NGINX 1 10 3 1 并尝试安装 Joomla CMS 但在第一个安装屏幕 example com installation index php 上 我注意到一
  • Selenium + Java 的 elementToBeClickable 问题

    所以 我有一个隐藏在警报下的元素 警报持续 10 秒 之后用户可以单击该元素 这是我处理这种情况的代码 WebElement create driver findElement By cssSelector div action menu
  • C# 根据 XSD 验证 XML [重复]

    这个问题在这里已经有答案了 可能的重复 使用 XSD 架构进行 Xml 验证 https stackoverflow com questions 572853 xml validation using xsd schema 我使用一些 C
  • 组合 ggplot2 对象时设置拼凑中的轴限制

    组合时ggplot2对象使用拼凑而成 https patchwork data imaginist com index html我希望能够有一个选项 可以轻松地为所有图设置一个选项 使其具有相同的 x 轴和 或 y 轴范围 reprex l
  • Busboy 文件上传中出现“Unexpected end of multipart form”错误

    我正在使用 Busboy 在 Node Express 应用程序中上传文件 我收到错误Unexpected end of multipart form和应用程序崩溃 每当我尝试治疗失眠的方法时 都没有效果 在显示 Busboy 不是构造函数
  • 创建 Uri uri 时应用程序崩溃

    package com example renu customlead import android content Context import android content ContextWrapper import android
  • 如何将参数发送到流中的引用方法(java 8)?

    我有一个活动列表 Activity 我想确定表单的数据结构Map String DateTime 不是持续时间或期间 DateTime这是必须的 映射 对于每项活动 在监控期间计算的总持续时间 班级活动有 activityLabel Str
  • 启用 viewBinding 功能失败(Android Studio 3.6)

    我已经安装了 Android Studio 3 6 Canary 12 并且我想使用viewBinding feature 根据文档 我将此代码放入我的 build gradle 应用程序模块 中 android viewBinding e
  • R 闪亮应用程序的 twitter bootstrap 弹出窗口 - html 被解释为文本内容 - 为什么?

    我想将 Twitter 引导框架中的弹出窗口添加到闪亮的应用程序中 一切正常 除了 认为html true标签没有效果 shinyUI pageWithSidebar headerPanel Header sidebarPanel acti
  • 如何跟踪服务 firebird

    如何使用delphi xe10跟踪服务firebird服务器的所有事件 这是我的代码 my TIBControlService Create Self my ServerName 127 0 0 1 3050 my Protocol TPr
  • Subversion 快速解决所有冲突

    当我遇到多个冲突时 有没有办法通过告诉 SVN 保留存储库中的版本来解决所有冲突 不幸的是 我们仍在使用 1 4 我相信如果你运行命令svn revert R 您基本上撤消了对工作副本的所有更改 如果存在冲突的文件 SVN 会放弃您的更改并
  • 使用时初始化缓存

    假设我有以下事件 做一点事 取东西 获取成功的东西 DoSomething做一些需要一些缓存数据的事情 当我触发事件时 我想查看缓存并对其执行某些操作 如果存在 如果没有 那么我想获取它 等待它进入缓存 然后重试 我想出了以下解决方案 但感