RxJs Observables:在更多异步请求后运行 retryWhen

2023-11-26

我的用例是:

  1. 用户从我们的 API 请求资产,由于 JWT 过期而失败(作为 httpOnly cookie 传递) - API 返回 401 状态代码。
  2. 我们再次使用refresh_token对它们进行身份验证(无需用户执行任何操作),以通过客户端向auth0发出的请求检索新的JWT。
  3. 我们将该新 JWT 发送到我们的 API,将其设置为 httpOnly cookie 以替换过期的 cookie。
  4. 然后,我们要重试用户在步骤 1 中向 API 发出的原始请求。

我正在尝试在 Redux 应用程序中使用 Observablesredux-observable。如果您能想到另一种方法来使上述用户流程正常工作,我将很高兴听到如何做。

注意。我在用着rxjs V5

export const fetchAssetListEpic = (action$, store) => {
  return action$.ofType('FETCH_ASSET_LIST')
  .switchMap( action => {
    const options = {
      crossDomain: true,
      withCredentials: true,
      url: uriGenerator('assetList', action.payload)
    };
    return ajax(options);
  })
  .map(fetchAssetListSuccess)
  .retryWhen(handleError)
  .catch(redirectToSignIn);
};

function handleError(err) {
  return (err.status === 401) ? 
  /* Authenticate here [Step 2] */
  /* Send new JWT to API [Step 3] */
  /* If successful make original request again [Step 4] */
  :
  Observable.throw(err);
}
  
function redirectToSignIn() {
  /*I will redirect here*/
}

到目前为止,我能够完成步骤 1、2 和 3,但不太确定添加步骤 4 的方法。我可能完全偏离目标,但任何帮助都会很棒!


您可能不想做的一件事是允许错误进入顶级流。即使你做了一个catch你已经有效地杀死了顶级流。因此,除非您的重定向是通过诸如反应路由器之类的东西进行硬重定向而不是软重定向,否则您将无法再使用这个史诗。

因此,我想说您希望将大部分逻辑封装在switchMap:

function withAuthorizedFlow(source) {
  return source
    .map(fetchAssetListSuccess)
    // retryWhen takes a callback which accepts an Observable of errors
    // emitting a next causes a retry, while an error or complete will
    // stop retrying
    .retryWhen(e => e.flatMap(err => 
      Observable.if(
        // Returns the first stream if true, second if false
        () => err.status === 401,
        reauthenticate, // A stream that will emit once authenticated
        Observable.throw(err) // Rethrow the error
      ))
    )
    .catch(redirectToSignIn);
}

/** Within the epic **/
.switchMap(({payload}) => {
  const options = {
    crossDomain: true,
    withCredentials: true,
    url: uriGenerator('assetList', payload)
  };

  // Invoke the ajax request
  return ajax(options)
    // Attach a custom pipeline here
    // Not strictly necessary but it keeps this method clean looking.
    .let(withAuthorizedFlow);
})

指某东西的用途let上面是完全可选的,我把它放进去是为了清理函数。本质上,您希望将错误包含在内部流中,以便它无法停止外部流。我不确定是哪一个ajax您正在使用的库,但您还应该确认它实际上会返回冷Observable否则你需要将它包裹在一个defer阻止为了retryWhen上班。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RxJs Observables:在更多异步请求后运行 retryWhen 的相关文章

随机推荐

  • Pandas Dataframe 到 JSON 层次结构

    我已经详尽地审查 尝试了与这一挑战相对应的所有其他问题的实现 但尚未找到解决方案 问题 如何将员工和主管对转换为分层 JSON 结构以用于 D3 可视化 级别数量未知 因此它必须是动态的 我有一个包含五列的数据框 是的 我意识到这不是 Of
  • 具有特定格式的日期到 XMLGregorianCalendar

    我得到一个 Date 对象 我需要将其转换为 XMLGregorianCalendar 特定格式 我尝试了以下方法 String formattedDate sdf format categoryData getBulkCollection
  • k&r 与位操作混淆

    练习是 编写一个函数 setbits x p n y 返回 x 并将从位置 p 开始的 n 位设置为 y 最右边的 n 位 其他位保持不变 我尝试的解决方案是 include
  • 按字典中的值返回键[重复]

    这个问题在这里已经有答案了 我正在尝试返回给定值的字典中的键 在这种情况下 如果 b 在字典中 我希望它返回 b 所在的键 即2 def find key input dict value if value in input dict va
  • 为什么 std::packaged_task 无效?

    使用MSVC2012 以下代码将按预期编译并运行 std packaged task lt int gt task gt int std cout lt lt hello world lt lt std endl return 0 std
  • 拉动刷新在 iOS WebView 中不起作用

    我已经实现了一个直接的WKWebView in iOS var refreshControl UIRefreshControl refreshControl addTarget self action Selector refreshWeb
  • Facebook Graph API (#190) 必须使用页面访问令牌调用此方法

    我通过 Facebook Graph API 从 Facebook 洞察中获取数据已有一年多了 最近开始了我所有的请求 比如 id insights 返回错误 190 This method must be called with a Pa
  • OpenSSL:无法使用 SSL_CTX_new() 创建 SSL_CTX *

    按照以下说明进行操作page 我正在尝试使用 openSSL 以安全的方式连接客户端 服务器 我无法创建 SSL CTX 如下所示 OpenSSL headers include openssl bio h include openssl
  • 在 ScrollView 中使用 onTouchListener 检测滑动

    我使用以下代码来检测活动中的滑动 getWindow getDecorView getRootView setOnTouchListener new OnTouchListener Override public boolean onTou
  • 使用 Python etree 更新 XML 元素和属性值

    我正在尝试使用Python 2 7ElementTree库来解析 XML 文件 然后用测试数据替换特定元素属性 然后将其保存为唯一的 XML 文件 我的解决方案的想法是 1 通过将文件读取为字符串来从 CSV 文件中获取新数据 2 在某些分
  • 使用相同代码但不同类型的重构方法

    我有几种方法可以做同样的事情 当与 MySQL 数据库连接时 保存或加载不同类型的参数 目前 我对每种类型都有不同的方法 如何组合这些方法以便它们支持不同的类型 下面是两个非常相似但使用不同类型的方法的示例 public static vo
  • 使用 Javascript 与 SQL 服务器握手

    我想尝试 作为学习练习 让我的 javascript 与 sql 聊天 var ws new WebSocket ws 127 0 0 1 1433 似乎没有被阻止的端口 所以理论上它应该可以工作 我正在寻找如何与 sql 服务器握手并与其
  • 显示带有嵌套 ListView 的 IGrouping<>

    我需要从数据访问层检索一组 Widget 按 widget Manufacturer 分组 以显示在一组嵌套的 ASP NET ListView 中 问题是 据我所知 嵌套 ListView 方法要求我在使用数据之前对数据进行整形 而且我无
  • 如何插入、更新和删除日历和事件

    有没有办法添加 删除和更新日历 和 有没有办法在日历中添加 删除和更新事件 Thanks 检查这个代码http code google com p android calendar provider tests source browse
  • AWS 安全组 - EC2 到 RDS

    我想问一下如何将 EC2 连接到 AWS 中的 RDP 我已将 EC2 安全组 包含 EC2 实例 添加到默认 RDP 组中 并且数据正在流动 连接正常 EC2 安全组已启用端口 80 至 0 0 0 0 0 并通过 SSH 连接到我的 I
  • 错误:不变违规:dangerouslyRenderMarkup(...):无法在工作线程中渲染标记

    设置状态导致第二次渲染后反应测试失败 到目前为止 JSDOM 和 Mocha 的测试进展顺利 到目前为止 还没有必要测试任何改变其状态的组件 我发现我的第一个问题是测试一个改变其状态的组件 错误 1 Reduced Test Case cu
  • JavaFX 在全屏模式下更改场景

    我在使用 JavaFX 时遇到问题 我创建了两个场景和切换按钮 当我单击该按钮时 我正在改变场景 但早些时候我将全屏设置为 true 按下按钮后 Windows 任务栏会显示一会儿 有没有办法在不显示此任务栏的情况下更改场景 有代码 主班
  • 是否有所有国际句号标点符号的字符集?

    我正在尝试将 utf 8 字符串解析为 一口大小 的段 例如 我想将文本分解为 句子 是否存在与所有语言的句子结尾相对应的字符 或正则表达式 的全面集合 我正在寻找能够捕捉拉丁语句号 感叹号和问号 中文和日文句号等的东西 类似上面的东西 但
  • 未捕获的 InvalidValueError:不是功能或功能集合

    看到最近的一个video由 Google 开发人员制作 我决定制作一张英国的区域地图 这个网站上提到了几种可能性 但我后来不得不放弃 所以我最终使用了这个网站 数据下载的示例页面 http mapit mysociety org area
  • RxJs Observables:在更多异步请求后运行 retryWhen

    我的用例是 用户从我们的 API 请求资产 由于 JWT 过期而失败 作为 httpOnly cookie 传递 API 返回 401 状态代码 我们再次使用refresh token对它们进行身份验证 无需用户执行任何操作 以通过客户端向