【问题标题】:EmptyError: no elements in sequenceEmptyError:序列中没有元素
【发布时间】:2021-12-10 15:54:21
【问题描述】:

我正在将我的 Angular2 应用程序从 2.0.0 升级到 2.3.0,我遇到了以下错误。关于为什么的任何想法?我看到了另一个帖子(Angular 2.0.1 Router EmptyError: no elements in sequence),但是在尝试了这个之后,问题仍然存在。是什么导致了这个错误?

Error: Uncaught (in promise): EmptyError: no elements in sequence
Error: no elements in sequence
    at EmptyError.ZoneAwareError (zone.js:672)
    at new EmptyError (EmptyError.ts:13)
    at FirstSubscriber._complete (first.ts:161)
    at FirstSubscriber.Subscriber.complete (Subscriber.ts:122)
    at Subject._subscribe (Subject.ts:109)
    at Subject.Observable.subscribe (Observable.ts:98)
    at Observable._subscribe (Observable.ts:158)
    at Observable.subscribe (Observable.ts:98)
    at Observable._subscribe (Observable.ts:158)
    at FirstOperator.call (first.ts:82)
    at Observable.subscribe (Observable.ts:96)
    at Object.subscribeToResult (subscribeToResult.ts:32)
    at MergeAllSubscriber._next (mergeAll.ts:82)
    at MergeAllSubscriber.Subscriber.next (Subscriber.ts:95)
    at MapSubscriber._next (map.ts:80)
    at resolvePromise (zone.js:475) [angular]
    at resolvePromise (zone.js:460) [angular]
    at /libs/zone.js/dist/zone.js:509:17 [angular]
    at Object.onInvokeTask (core.umd.min.js:32) [angular]
    at ZoneDelegate.invokeTask (zone.js:261) [angular]
    at Zone.runTask (zone.js:151) [<root> => angular]
    at drainMicroTaskQueue (zone.js:405) [<root>]
    at ZoneTask.invoke (zone.js:336) [<root>]ErrorHandler.handleError @ core.umd.min.js:31next @ core.umd.min.js:32generatorOrNext.object.schedulerFn @ core.umd.min.js:32SafeSubscriber.__tryOrUnsub @ Subscriber.ts:238SafeSubscriber.next @ Subscriber.ts:190Subscriber._next @ Subscriber.ts:135Subscriber.next @ Subscriber.ts:95Subject.next @ Subject.ts:61EventEmitter.emit @ core.umd.min.js:32NgZone.triggerError @ core.umd.min.js:32onHandleError @ core.umd.min.js:32ZoneDelegate.handleError @ zone.js:233Zone.runGuarded @ zone.js:129_loop_1 @ zone.js:416drainMicroTaskQueue @ zone.js:425ZoneTask.invoke @ zone.js:336

我还注意到,当我尝试更改为使用 Guards 的路由时,会引发 NavigationError 对象。但只有上面的错误是控制台中显示的。

NavigationError {id: 2, url: "/home", error: EmptyError}

我有点不知所措,如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 所以请显示你的路线..
  • 我认为这与守卫有关,我也在努力解决。

标签: angular angular2-routing


【解决方案1】:

在使用带有 angular(版本 4/5)的 RxJS 5.5.3 时会发生此错误,因此只需跳过 RxJS 5.5.3,并通过将 "rxjs": "^5.5.4" 添加到项目 package.json 来使用 RxJS 5.5.4。


在 RxJS 5.5.4 出来之前回答:(旧的,不要这样做)

  • 在 package.json source 上锁定版本 5.5.2 RxJS
  • 在空路径上添加 pathMatch:'full' source

看起来这是一个RxJS issue,应该很快就会修补。 source

【讨论】:

  • 可以确认,刚升级到 RxJS 5.5.3 也有同样的问题。
  • 这里也一样。坏了..谢谢golfadas。让我修好我们的
  • 也确认了。 5.5.3 和 Angular 5.0.0(测试版)出了点问题
  • 第二个选项 Works ,将pathMatch: 'full' 添加到您的所有路线,检查thisthis
  • rxjs 6.5.2 和 Angular 8 有这个问题。我的空路由已经有了 pathMatch: 'full'。
【解决方案2】:

就我而言,当我在 Observable 中使用 first() 时遇到了这些错误,而 takeUntil()first() 之前发出。

例子:

let test$ = new ReplaySubject(1);
let testAux$ = new ReplaySubject(1);
let test2$ = test$.asObservable().takeUntil(testAux$.asObservable());
test2$.first().subscribe(() => console.log('first!'));
testAux$.next(null);

很难发现问题,因为我在一个名为 first() 的不同类(在不同文件中)使用的服务中返回了 observabletakeUntil(),并且在页面期间收到错误导航(因为 takeUntil() 收到了一个 observable ,它在前一页被销毁时发出),并且它看起来是导航本身的问题。

最奇怪的是错误发生在next() 被调用时,而不是在subscribe() 的第二个参数中,导致导航过程本身失败。我不知道 rxjs 团队是否选择了这个特性来表现这种行为,因为它使得隔离问题变得更加困难,而且,主要问题是,生产者收到一个错误,因为消费者,这对我来说似乎是一个糟糕的设计。

根据this comment

.first() 将只发出一项或抛出错误[...] 如果您想从 observable 中获取最多一项,请使用 .take(1)

更新(2020-08-31)

似乎实际上可以通过在订阅中包含第二个参数来接收错误来处理错误,例如以下情况:

const test$ = new ReplaySubject(1);
const testAux$ = new ReplaySubject(1);
const test2$ = test$.asObservable().takeUntil(testAux$.asObservable());
test2$.first().subscribe(() => console.log('first!'), () => console.log('first error'));
testAux$.subscribe(() => console.log('another'), () => console.log('another error'));
console.log('1');
testAux$.next(null);
console.log('2');

记录:

1
first error
another
2

(在这种情况下,您不会看到 No elements in sequence 错误)

但是,如果您最多希望收到 1 件商品(但没有收到也可以),那么 take(1) 仍然是更好的方法,而且我默认推荐这种方式,而不是 @987654340 @。

【讨论】:

  • 按照这里的建议将 first() 更改为 take(1) 为我修复了类似的错误消息“错误:序列中没有元素”。
  • 在我的例子中,一个组件在一个空的 Observable 上调用 .first()(Observable 是由服务的模拟实现返回的,所以它只在单元测试中失败)。
  • @mamacdon 这里也一样。好收获!
  • 当你的ngAfterViewInit 中有一个takeUntil(this.destroy$), first() 的东西时,这件事很容易发生。在你的销毁中,你触发了你的destroy$ 标志。如果您加载一个组件,就会发生这种情况,但不知何故,您从ngAfterViewInit 中的父组件中快速删除它。查看所有takeUntil(this.destroy$),后跟first(),并将其替换为take(1)
【解决方案3】:

您需要更改为:

canActivate(route: ActivatedRouteSnapshot): Observable<boolean>{
   return new Observable<boolean>(resolve => {
      resolve.next(true);
      resolve.complete();
  });
}

=================

我不确定为什么,但对我来说,这个错误是由 CanActivate 路由器防护使用 observables 引起的。然而,转向承诺解决了这个问题。

我是从这里搬过来的:

canActivate(route: ActivatedRouteSnapshot): Observable<boolean>{
     return new Observable<boolean>(resolve => {

          resolve.complete(true);
        //or
          resolve.complete(false);

    });
}

到这里:

canActivate(route: ActivatedRouteSnapshot){
     return true;
        //or
          return false;

    });
}

【讨论】:

  • 我把我的警卫换成了 Promises 来试试这个。有用!我不知道为什么这很重要,但我会继续这样做。谢谢 Victor96!
  • 更改 resolve.complete(true);解决。下一个(真);它应该可以工作。根据angular.io/docs/ts/latest/guide/router.html#!#guards >因此,路由保护可以返回一个 Observable 或一个 Promise 并且路由器将等待 observable 解析为 true 或 false。并且 complete 不返回任何元素,但 next 会。
  • 对我来说,resolve.next(true); resolve.complete() 不起作用,但使用 Promise 可以。
  • observer.complete(value) 什么都不做......你想做observer.next(true); observer.complete 或只是Observable.of(true)。不幸的是,这个答案是不好的建议。
【解决方案4】:

有同样的问题,因为我在 this.http.get(); 之后做了一个 .first(); Http.get 返回一个冷的 observable,所以 first 是不必要的,因为冷的 observable 会自动取消订阅。

this.http.get().pipe(first()); -> EmptyError:序列中没有元素

【讨论】:

  • 你在这件事上很省钱,时间紧迫,不会想到这一点。
【解决方案5】:

将此属性添加到您的路线。

pathMatch: 'full

例如。

{ pathMatch: 'full', path: "", component: HomeComponent }

它对我有用。

【讨论】:

  • 无需更改应用程序路由即可解决此问题(截至今天)。一个新版本的 RxJS 出来了,修复了这个错误。将 RxJS 升级到 5.5.4 版本。
【解决方案6】:

对于因错误消息而来到这里的任何人,这发生在我们身上是因为我们返回了一个 void Observable。您需要至少返回一些值,例如“true”。

return of(true);

【讨论】:

  • of() 更改为 of(undefined) 对我有用
【解决方案7】:

我还将分享我在使用 last() 运算符时在 RxJS 6.5.3 中遇到此错误的经验。 这个问题可以通过应用一个默认值来解决,比如:

.pipe(
  last(null, []) // predicate = null, defaultValue = []
)

【讨论】:

    【解决方案8】:

    就我而言,使用 rxjs 的 5.5.12 版本,我在 CanActivate 场景中遇到了麻烦。但最终对我来说解决方案非常简单。我从

    更改了我的代码
    const guard: Subject<boolean> = new Subject<boolean>();
    

    const guard: ReplaySubject<boolean> = new ReplaySubject<boolean>(1);
    

    打电话

    guard.next(...);
    guard.complete();
    

    稍后。那成功了。所以在我的场景中不需要 .first 也不需要承诺。

    【讨论】:

      【解决方案9】:

      我在 Angular 6 / RxJs 6 中遇到了这个问题,发现这是因为我的守卫有一个重定向并在它之后完成。

      之前:

      if (!res) {
        this.router.navigate(['/']);
        observer.complete(); // <-- This was the offender
      }
      

      之后:

      if (!res) {
        this.router.navigate(['/']);
      }
      

      【讨论】:

        【解决方案10】:

        你必须返回整个响应而不是 response.body

        【讨论】:

        【解决方案11】:

        以上方法均无效。这对我有用。在路由定义中:

        { path: '', component: WelcomeComponent, pathMatch: 'full' },
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-08-18
          • 2019-03-21
          • 1970-01-01
          • 2018-05-16
          • 2023-04-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多