当前位置: 首页 > 知识库问答 >
问题:

如何处理异步本地存储与角2?

颛孙国源
2023-03-14

我正在使用angular async本地存储模块设置本地存储中令牌的到期时间。

import { AsyncLocalStorage } from 'angular-async-local-storage';

const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());

this.localStorage.setItem('expires_at', expiresAt).subscribe(() => {});

然后,我有一个在用户登录时调用的函数,该函数检查令牌是否仍然有效:

get isAuthenticated(): boolean {
    let res;
    this.localStorage.getItem('expires_at')
        .subscribe((val) => {
            let expiresAt = JSON.parse(val);
            res = (expiresAt && this.loggedIn) ? (new Date().getTime() < expiresAt) : false;
        });

    return res;
}

这里的问题是localStorage.getItem()返回一个可观察的。所以当我们在可观察的上调用。订阅时,它被异步调用,这意味着我们不会阻塞,直到结果准备好,所以代码直接通过并执行返回res语句,此时res是未定义的,因为订阅箭头函数中的代码尚未执行,因为结果尚未准备好。

所以我需要一些关于解决这个问题的最佳方法的建议是什么?我想到的一种方法是尝试并阻塞,直到结果准备就绪,但鉴于我们使用的是html" target="_blank">异步本地存储模块,这似乎是一种反模式。但也许我需要的只是一个简单的同步本地存储模块?或者这被认为是不好的做法?任何帮助都很好,谢谢!

共有2个答案

空谦
2023-03-14

我假设您的用户已经期望等待异步登录加载,因此您可以使用flatMap将localStorage调用链接到它:

isAuthenticated(): Observable<number> {
    return this.localStorage.getItem('expires_at')
    .map((val) => {
            let expiresAt = JSON.parse(val);
            return (expiresAt && this.loggedIn) ? (new Date().getTime() < expiresAt) : 0;
        });
}

yourLoginFunction()
.flatMap(loginRes => {
    return this.isAuthenticated()
})
.subscribe(res => {
    // handle accordingly
}

请注意,isAuthenticated()不能具有类型boolean可见

何宏博
2023-03-14

长话短说:在您的情况下,我会选择同步本地存储解决方案。

长故事:

在Angular中遇到这样的情况(同步vs异步)时,我总是会得到以下两种解决方案之一:

1)让isAuthentiated返回可观察的,并将您的本地存储映射为可观察的返回true/false

get isAuthenticated(): Observable<boolean> {
    return this.localStorage.getItem('expires_at').pipe(
        map((val) => {
            let expiresAt = JSON.parse(val);
            let res = (expiresAt && this.loggedIn) ? (new Date().getTime() < expiresAt) : false;
            return res;
        })
    );
}

2) 按照您的建议使用同步解决方案

什么是最佳做法取决于情况。根据我的经验,如果你以可观察的方式去做,你最终会得到更多的代码处理

另一方面,如果您使用同步解决方案,您的代码会简单得多,但在某些情况下,您的应用程序可能会变得非常慢(想象一下在缓慢的移动网络上同步HTTP请求)。

因此,如果你只从本地存储中获得一个小项目,你不会看到差异。另一方面,这个库为IndexedDb提供了相同的接口,其中最大限制可能是2Gb的数据,因此您可以将整个集合保存在那里,如果您使用异步方式,那么您的应用程序速度可能会很大。

 类似资料:
  • 问题内容: 我想通过将所有Cookie移到本地存储中来减少其加载时间,因为它们似乎具有相同的功能。除了明显的兼容性问题以外,使用本地存储替换cookie功能是否有任何利弊(尤其是性能方面的优势)? 问题答案: Cookies和本地存储有不同的用途。Cookies主要用于读取 服务器端 ,本地存储只能由 客户端 读取。所以问题是,在您的应用程序中,谁需要此数据-客户端还是服务器? 如果它是您的客户端

  • 问题内容: 除了是非持久性的并且仅限于当前窗口之外,会话存储与本地存储相比是否还有其他好处(性能,数据访问等)? 问题答案: localStorage和sessionStorage都扩展了Storage。除了的预期的“非持久性”外,它们之间没有区别。 也就是说,存储在中的数据将 一直保留到明确删除为止 。所做的更改将被保存,并且可用于当前和将来对该站点的所有访问。 对于, 更改仅在每个选项卡上可用

  • 在Facebook关于Flux架构的演讲中,Jing在12:17提到dispatcher强制要求,在当前操作被商店完全处理之前,不能调度任何操作。 这里的调度员是执行没有级联效应的主要部分;一旦一个操作进入商店,在商店完全处理完它之前,您不能再放入另一个操作。 那么,我的问题是,如何正确地处理可能从存储区中删除的长时间运行的异步操作(例如,Ajax请求,或处理其他外部异步API)--任何阻止完成操

  • 问题内容: 我有一个存储大量客户端数据的问题,我无法确定哪种方法更好。现在,我正在使用AngularJS的cacheFactory,它可以正常工作,但是所有数据都会通过新会话重新加载。值得使用本地存储代替吗? 问题答案: 如果您的目标是存储客户端数据和持久性数据,则不能使用$ cacheFactory ,它只缓存当前会话的数据。 一种解决方案是使用新的本地存储API。这个很棒的Angular模块为

  • 在上一节解决了如何对资源请求进行拦截代理之后,要实现网页的离线缓存还需要解决本地存储的选择与管理问题。 从前面学习中我们知道,处于同一作用域下的网页会共用一个 Service Worker 线程,这个 Service Worker 会同时处理来自不同页面的资源请求的拦截和响应,因此基于性能上的考虑,Service Worker 在设计标准时就要求了任何耗时操作都必须异步实现。这也就导致了在 Ser

  • 这个标题听起来像是重复的,但我找不到我这个问题的答案。 我想在本地计算机上克隆一个git存储库。但是,当我尝试使用shell执行此操作时,我会得到一个错误。大多数文件都被签出了,但由于某种原因,其中一个图像文件引起了麻烦,我得到了错误“致命:无法签出工作树”和“警告:克隆成功,但签出失败”。所以我现在所做的是从github下载repo文件作为一个zip文件,并将它们解压缩到我的本地目录中。所以现在