使用案例:每分钟调用一个函数(60000毫秒),调度存储操作以获取lastUpdated
项目的状态,在响应和过滤时,更新存储,更新的存储被读取为可观察的并显示在视图中).只要Web应用程序处于打开状态(如此无限期),就需要进行此操作.
目前,我正在使用这个:
this.refreshDate = window.setInterval(
() => this.store.dispatch(new FetchLastUpdate())
, 60000);
Run Code Online (Sandbox Code Playgroud)
当视图被销毁/卸载时,我删除间隔如下:
if (this.refreshDate) {
clearInterval(this.refreshDate);
}
Run Code Online (Sandbox Code Playgroud)
这是有效/有效的,还是很麻烦?
为什么我要使用RxJS轮询策略,如:
interval(60000)
.pipe(
startWith(0),
switchMap(() => this.store.dispatch(new FetchLastUpdate()))
);
Run Code Online (Sandbox Code Playgroud)
要么
timer(0, 60000)
.pipe(
switchMap(() => this.store.dispatch(new FetchLastUpdate()))
);
Run Code Online (Sandbox Code Playgroud)
TL; DR: window.setInterval()
vs. RxJS timer()
/interval()
使用RxJS函数来设置间隔或执行轮询有很大的好处,这些好处在选定的答案中也可以在注释中解释,但是(通过评论中的讨论)得出的结论是,对于" 本帖子开头的用例 "部分,没有必要使用RxJS,事实上如果你没有在你的程序的任何其他部分使用RxJS,请不要仅为此导入它,但在我的情况下,我有已导入并在其他地方使用RxJS.
我已将Angular 5应用程序升级到6.0.1,将RxJs升级到6.1.0.
在我的一项服务中,我有以下导入:
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
Run Code Online (Sandbox Code Playgroud)
但是,我现在收到以下错误:
Module'"... node_modules/rxjs/observable/ErrorObservable"'没有导出的成员'ErrorObservable'.
我在网上搜索如何在rxjs6或名称中导入它
ErrorObservable
Run Code Online (Sandbox Code Playgroud)
已经改变.
我用它作为升级过程的指南:
有谁知道如何解决这个导入?
我正在添加rxjs_compat
到我的项目中以转移到v6库.
但是,现有HttpInterceptor
的全局错误处理不再编译.不知道该去哪里.尝试各种各样.尝试所有的类型不匹配.
import { Injectable } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse,
HttpErrorResponse
} from "@angular/common/http";
import { Observable, of, empty } from "rxjs";
import { ToastrService } from "ngx-toastr";
import { environment } from "../../environments/environment";
import { catchError, map } from "rxjs/operators";
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private toastr: ToastrService) {}
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError(err => of(HttpErrorResponse)),
map(err => {
let message: string; …
Run Code Online (Sandbox Code Playgroud) 正如预期的那样,以下代码在 5 秒后发出 42:
const valueObservable = of(42).pipe(delay(5000));
valueObservable.subscribe((value) => console.log(value));
Run Code Online (Sandbox Code Playgroud)
但是,订阅时会立即抛出版本错误:
const throwingObservable = throwError(new Error('My Error')).pipe(delay(5000));
throwingObservable.subscribe((value) => console.log(value), (error) => console.error(error));
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?如何延迟抛出错误?
cdSo我正在尝试将我的一些Angular 5代码迁移到6,并且我理解rxjs使用.pipe()运算符所需的大多数更改.它的工作方式与"pipable"操作一样.
但是,行为catchError()
与.catch()
运营商不同.在rxjs 6之前,我使用.catch()
运算符将错误输入转换为一个一致的错误对象,然后可以在`.subscribe()中捕获.
getAlbums(): Observable<Album[]> {
return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
.map(albumList => this.albumList = albumList)
.catch(new ErrorInfo().parseObservableResponseError);
}
Run Code Online (Sandbox Code Playgroud)
new ErrorInfo().parseObservableResponseError
是一个函数,它将一个错误对象作为输入,并将输入错误解析为一个带有规范化对象的简单错误对象.捕获返回Observable<any>
:
parseObservableResponseError(response): Observable<any> {
let err = new ErrorInfo();
...
return Observable.throw(err);
}
Run Code Online (Sandbox Code Playgroud)
这对于轻松处理rxjs5错误非常有用 - 错误基本上被捕获为管道的一部分,然后抛出一个众所周知的错误结构,可以捕获.subscribe()
错误函数.
然后将相同的代码移动到rxjs 6并使用.pipe()
我尝试执行以下操作:
getAlbums(): Observable<Album[]> {
return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
.pipe(
map(albumList => this.albumList = albumList),
catchError(new ErrorInfo().parseObservableResponseError)
);
}
Run Code Online (Sandbox Code Playgroud)
但是这不起作用,因为catchError现在将结果返回Observable<any>
到管道中,这不是我想要的.从本质上讲,我只想像以前一样重新抛出任何错误.
错误TS2322:输入'Observable <{} | 专辑[]>'不能分配给'Observable'类型
如何模拟旧的操作员.catch()
行为?
更新:
经过多次讨论后,显示的代码刚开始工作而没有给我一个构建错误.老实说,我不知道为什么它之前的错误消息失败了,但现在正在工作.@cartant在评论中的建议是指定结果的明确方式,也是有效的.
我只想对我的类类型"类别"的可观察对数据进行排序.所以Observable <Category []>我想排序.
所以我用它升级到Angular6和rxjs6.我知道的一个可能是简单的Typescript的问题是如何进行"排序"操作,如:
sort((x,y) => x.description < y.description ? -1 : 1)
Run Code Online (Sandbox Code Playgroud)
在新的Angular6里面?我曾经在5年做过这个
var response = this.http.get<Category[]>(this.endpoint);
.map((result: Response) => this.alphabetize(result));
alphabetize = (result: Response) => this.Categories = result.json()
.sort((x,y) => x.description < y.description ? -1 : 1)
Run Code Online (Sandbox Code Playgroud)
它工作得很好.现在在Angular希望你使用它的HttpCLIENTModule和HttpClient中它更简单:
var data = this.http.get<Category[]>(this.endpoint);
Run Code Online (Sandbox Code Playgroud)
我只是将魔术<(对象)>放在我的端点之前,它就是为我做的.凉.但是我没有看到你如何容易地从物体中取出它,使用Source,Pipe,from,of.我知道它可能很简单我只是不知道语法.
我正在将我的Angular 5应用程序升级到Angular 6,因此从rxjs 5升级到rxjs 6,我在迁移以下代码时遇到了麻烦:
const myObservable = Observable.create(subscriber => {
// do something with the subscriber
}).share();
Run Code Online (Sandbox Code Playgroud)
特别是我收到这个错误:
类型错误:Observable_1.Observable.create(...)的份额是不是functionTypeError:Observable_1.Observable.create(...)的份额不大.
我刚刚在我的角度项目中更新了很多包.
旧的package.json:
{
"name": "data-jitsu",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^5.2.10",
"@angular/cdk": "^5.2.5",
"@angular/common": "5.2.7",
"@angular/compiler": "5.2.7",
"@angular/core": "5.2.7",
"@angular/forms": "5.2.7",
"@angular/http": "5.2.7",
"@angular/material": "^5.2.5",
"@angular/platform-browser": "5.2.7",
"@angular/platform-browser-dynamic": "5.2.7",
"@angular/router": "5.2.7",
"@types/youtube": "0.0.29",
"angular-froala-wysiwyg": "^2.7.2-1",
"angular2-materialize": "^15.1.10",
"angularfire2": "^4.0.0-rc0",
"core-js": "^2.4.1",
"d3": "^4.13.0",
"firebase": "^3.9.0",
"hammerjs": "^2.0.8",
"jquery": "^3.0.0",
"materialize-css": "^0.100.2",
"ngx-youtube-player": "0.0.41",
"rxjs": "^5.5.6",
"zone.js": …
Run Code Online (Sandbox Code Playgroud) 为了避免组件内部的 Observable 内存泄漏,我takeUntil()
在订阅 Observable 之前使用了运算符。
我在我的组件中写了这样的东西:
private unsubscribe$ = new Subject();
ngOnInit(): void {
this.http
.get('test')
.pipe(takeUntil(this.unsubscribe$))
.subscribe((x) => console.log(x));
}
ngOnDestroy(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete(); // <--- ??
}
Run Code Online (Sandbox Code Playgroud)
最后我的问题如下:
我需要写this.unsubscribe$.complete();
还是next()
就够了?
是unsubscribe$
要由垃圾收集器没有完成被抓住?
请解释是否存在差异或无关紧要。我不希望我的组件出现内存泄漏。
旧代码使用rxjs v5.5.12,我们将相同的代码复制到了使用rxjs v6.4.0的新项目中。当我们尝试运行测试用例时,我们得到了这个错误。
旧代码:
import * as ObservableEvents from 'rxjs/Observable/fromEvent';
spyOn(ObservableEvents, 'fromEvent').and.returnValue(new Subject<any>().asObservable());
Run Code Online (Sandbox Code Playgroud)
新代码:
import * as rxjs from 'rxjs';
spyOn(rxjs, 'fromEvent').and.returnValue(new Subject<any>().asObservable());
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我们都会收到此错误:
错误:: fromEvent未声明为可写或没有设置器
我们找不到有效的资源来解决此问题。
更新#1
我们尝试使用
import * as rxjs from 'rxjs';
spyOn(jasmine.createSpyObj(rxjs), 'fromEvent').and.returnValue(new Subject<any>().asObservable());
Run Code Online (Sandbox Code Playgroud)
但是这次,我们得到了
createSpyObj需要一个非空数组或方法名称对象来创建用于抛出的间谍
更新#2:
我们使用了@ Omair-Nabiel的代码,现在收到一个新错误
TypeError: Object(...) is not a function
at XxxPopoverDirective.fromEvent [as createPopover] (http://xxx:xxxx/src/app/shared/xxx/xxx.directive.ts?:113:37)
at XxxPopoverDirective.createPopover [as mouseClick] (http://xxx:xxxx/src/app/shared/xxx/xxx.directive.ts?:70:14)
at runTest (http://xxx:xxxx/src/app/shared/xxx/xxx.directive.spec.ts?:181:19)
Run Code Online (Sandbox Code Playgroud)
xxx.directive.ts
line 113-> this.componentRef && this.componentRef.destroy();
this.componentRef = null;
line 70-> constructor(
...
private resolver: ComponentFactoryResolver,
...
) …
Run Code Online (Sandbox Code Playgroud)