Skip to content

every operator sending multiple values when re-entrant #7425

@anthonyrota

Description

@anthonyrota

Describe the bug

The every operator can send multiple false's when, in the Subscriber's next, the Observable it is operating on sends a new value into the operator, because the middle subscriber's next handler will be recursively called before the complete is sent.

Related: #1967 #2100

  next: (value) => {
    if (!predicate.call(thisArg, value, index++, source)) {
      destination.next(false); # If inside this function call, the source sends a new value that the predicate rejects, two or more false's can be sent.
      destination.complete();
    }
  },

Also, it can send next(false) then next(true) then complete if re-entrant complete within the next commented.

Expected behavior

The circumstances leading to this shouldn't really happen but if it does, maybe consider guarding against it so only a single false is pushed?

Reproduction code

import { Subject } from 'rxjs';
import { every } from 'rxjs/operators';
{
  console.log('scen 1')
  const subj = new Subject();
  let i = 0;
  subj.pipe(every(() => false)).subscribe({
    next: (value) => {
      console.log('next', value, i);
      if (++i < 5) {
        subj.next(undefined);
      }
    },
    complete: () => {
      console.log('end');
    },
  });
  subj.next(undefined)
}
{
  console.log('scen 2')
  const subj = new Subject();
  subj.pipe(every(() => false)).subscribe({
    next: (value) => {
      console.log('next', value);
      subj.complete();
    },
    complete: () => {
      console.log('end');
    },
  });
  subj.next(undefined)
}

Reproduction URL

https://stackblitz.com/edit/rxjs-22nsn5?file=index.ts

Version

8.0.0-alpha.12

Environment

No response

Additional context

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions