Skip to content

Commit

Permalink
feat: remove async iteration (#5492)
Browse files Browse the repository at this point in the history
* feat: remove async iteration

Removes experimental async iteration from Observable. Users that want this feature should really checkout https://github.com/benlesh/rxjs-for-await. There are too many edge cases for this, and also some uncertainty around cancellation behaviors we could provide. We may add this back in another iteration, but for now it is best in a separate library

BREAKING CHANGE: Removes support for `for await`. Use https://github.com/benlesh/rxjs-for-await instead.

* chore: remove unused file, fix lint

* chore: update side-effect golden files
  • Loading branch information
benlesh authored Jun 15, 2020
1 parent 1ae937a commit 8f43e71
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 152 deletions.
2 changes: 1 addition & 1 deletion integration/side-effects/snapshots/esm/ajax.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import "tslib";

2 changes: 0 additions & 2 deletions integration/side-effects/snapshots/esm/testing.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import "tslib";

var NotificationKind;

(function(NotificationKind) {
Expand Down
2 changes: 1 addition & 1 deletion integration/side-effects/snapshots/esm/websocket.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import "tslib";

74 changes: 10 additions & 64 deletions spec/Observable-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { expect } from 'chai';
import * as sinon from 'sinon';
import { Observer, TeardownLogic } from '../src/internal/types';
import { cold, expectObservable, expectSubscriptions } from './helpers/marble-testing';
import { Observable, config, Subscription, noop, Subscriber, Operator, NEVER, Subject, of, throwError, empty, interval } from 'rxjs';
import { map, multicast, refCount, filter, count, tap, combineLatest, concat, merge, race, zip, take, finalize } from 'rxjs/operators';
import { Observable, config, Subscription, noop, Subscriber, Operator, NEVER, Subject, of, throwError, empty } from 'rxjs';
import { map, multicast, refCount, filter, count, tap, combineLatest, concat, merge, race, zip } from 'rxjs/operators';

declare const rxTestScheduler: any;

Expand Down Expand Up @@ -36,7 +36,7 @@ describe('Observable', () => {
});

it('should send errors thrown in the constructor down the error path', (done) => {
new Observable<number>((observer) => {
new Observable<number>(() => {
throw new Error('this should be handled');
})
.subscribe({
Expand Down Expand Up @@ -68,7 +68,7 @@ describe('Observable', () => {
});

it('should reject promise when in error', (done) => {
throwError('bad').forEach((x) => {
throwError('bad').forEach(() => {
done(new Error('should not be called'));
}, Promise).then(() => {
done(new Error('should not complete'));
Expand Down Expand Up @@ -265,7 +265,7 @@ describe('Observable', () => {
});

source.subscribe({
error(err) {
error() {
/* noop: expected error */
}
});
Expand Down Expand Up @@ -655,7 +655,7 @@ describe('Observable.create', () => {
});

it('should send errors thrown in the passed function down the error path', (done) => {
Observable.create((observer: Observer<any>) => {
Observable.create(() => {
throw new Error('this should be handled');
})
.subscribe({
Expand Down Expand Up @@ -719,7 +719,7 @@ describe('Observable.lift', () => {
result.subscribe(
function (x) {
expect(x).to.equal(expected.shift());
}, (x) => {
}, () => {
done(new Error('should not be called'));
}, () => {
done();
Expand All @@ -745,7 +745,7 @@ describe('Observable.lift', () => {
result.subscribe(
function (x) {
expect(x).to.equal(expected.shift());
}, (x) => {
}, () => {
done(new Error('should not be called'));
}, () => {
done();
Expand All @@ -769,7 +769,7 @@ describe('Observable.lift', () => {
result.subscribe(
function (x) {
expect(x).to.equal(expected.shift());
}, (x) => {
}, () => {
done(new Error('should not be called'));
}, () => {
done();
Expand Down Expand Up @@ -909,7 +909,7 @@ describe('Observable.lift', () => {
function (x) {
expect(x).to.equal(expected.shift());
},
(x) => {
() => {
done(new Error('should not be called'));
}, () => {
expect(log).to.deep.equal([
Expand Down Expand Up @@ -939,57 +939,3 @@ describe('Observable.lift', () => {
}
});
});

if (Symbol && Symbol.asyncIterator) {
describe('async iterator support', () => {
it('should work for sync observables', async () => {
const source = of(1, 2, 3);
const results: number[] = [];
for await (const value of source) {
results.push(value);
}
expect(results).to.deep.equal([1, 2, 3]);
});

it('should throw if the observable errors', async () => {
const source = throwError(new Error('bad'));
let error: any;
try {
for await (const _ of source) {
// do nothing
}
} catch (err) {
error = err;
}
expect(error).to.be.an.instanceOf(Error);
expect(error.message).to.equal('bad');
});

it('should support async observables', async () => {
const source = interval(10).pipe(take(3));
const results: number[] = [];
for await (const value of source) {
results.push(value);
}
expect(results).to.deep.equal([0, 1, 2]);
});

it('should do something clever if the loop exits', async () => {
let finalized = false;
const source = interval(10).pipe(take(10), finalize(() => finalized = true));
const results: number[] = [];
try {
for await (const value of source) {
results.push(value);
if (value === 1) {
throw new Error('bad');
}
}
} catch (err) {
// ignore
}
expect(results).to.deep.equal([0, 1]);
expect(finalized).to.be.true;
});
});
}
22 changes: 0 additions & 22 deletions src/internal/Observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { throwError } from './observable/throwError';
import { observable as Symbol_observable } from './symbol/observable';
import { pipeFromArray } from './util/pipe';
import { config } from './config';
import { asyncIteratorFrom } from './asyncIteratorFrom';

/**
* A representation of any set of values over any amount of time. This is the most basic building block
Expand Down Expand Up @@ -396,24 +395,3 @@ function getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {

return promiseCtor;
}

export interface Observable<T> {
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
}

(function () {
/**
* We only add this symbol if the runtime supports it.
* Adding this adds support for subscribing to observables
* via `for await(const value of source$) {}`
*
* This passes muster in Node 9, which does not support
* async iterators. As well as working in Node 12, which does
* support the symbol.
*/
if (Symbol && Symbol.asyncIterator) {
Observable.prototype[Symbol.asyncIterator] = function () {
return asyncIteratorFrom(this);
};
}
})();
62 changes: 0 additions & 62 deletions src/internal/asyncIteratorFrom.ts

This file was deleted.

0 comments on commit 8f43e71

Please sign in to comment.