diff --git a/NON-STANDARD-APIS.md b/NON-STANDARD-APIS.md
index f68bc3ddc..978735f4b 100644
--- a/NON-STANDARD-APIS.md
+++ b/NON-STANDARD-APIS.md
@@ -103,3 +103,61 @@ for example, if you want to add MediaQuery patch, you should do like this.
```
+
+* rxjs
+
+`zone.js` also provide a `rxjs` patch to make sure rxjs Observable/Subscription/Operator run in correct zone.
+for detail please refer to [pull request 843](https://github.com/angular/zone.js/pull/843), the following sample code describe the idea.
+
+```
+const constructorZone = Zone.current.fork({name: 'constructor'});
+const subscriptionZone = Zone.current.fork({name: 'subscription'});
+const operatorZone = Zone.current.fork({name: 'operator'});
+
+let observable;
+let subscriber;
+constructorZone.run(() => {
+ observable = new Observable((_subscriber) => {
+ subscriber = _subscriber;
+ console.log('current zone when construct observable:', Zone.current.name); // will output constructor.
+ return () => {
+ console.log('current zone when unsubscribe observable:', Zone.current.name); // will output constructor.
+ }
+ });
+});
+
+subscriptionZone.run(() => {
+ observable.subscribe(() => {
+ console.log('current zone when subscription next', Zone.current.name); // will output subscription.
+ }, () => {
+ console.log('current zone when subscription error', Zone.current.name); // will output subscription.
+ }, () => {
+ console.log('current zone when subscription complete', Zone.current.name); // will output subscription.
+ });
+});
+
+operatorZone.run(() => {
+ observable.map(() => {
+ console.log('current zone when map operator', Zone.current.name); // will output operator.
+ });
+});
+```
+
+currently basically all `rxjs` API include
+
+- Observable
+- Subscription
+- Subscriber
+- Operators
+- Scheduler
+
+are patched, so they will run in the correct zone.
+
+## Usage.
+
+for example, in angular application, you can load this patch in your `app.module.ts`.
+
+```
+import 'zone.js/dist/zone-patch-rxjs';
+```
+
diff --git a/lib/rxjs/rxjs.ts b/lib/rxjs/rxjs.ts
index 1e14147b8..23d5287a9 100644
--- a/lib/rxjs/rxjs.ts
+++ b/lib/rxjs/rxjs.ts
@@ -340,7 +340,7 @@ import {rxSubscriber} from 'rxjs/symbol/rxSubscriber';
const action = workArgs.length > 0 ? workArgs[0] : undefined;
const scheduleZone = action && action[zoneSymbol];
if (scheduleZone && scheduleZone !== Zone.current) {
- return scheduleZone.run(work, this, arguments);
+ return scheduleZone.runGuarded(work, this, arguments);
} else {
return work.apply(this, arguments);
}
diff --git a/test/rxjs/rxjs.asap.spec.ts b/test/rxjs/rxjs.asap.spec.ts
new file mode 100644
index 000000000..1931bab8e
--- /dev/null
+++ b/test/rxjs/rxjs.asap.spec.ts
@@ -0,0 +1,51 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import * as Rx from 'rxjs/Rx';
+import {asyncTest} from '../test-util';
+
+describe('Scheduler.asap', () => {
+ let log: string[];
+ let errorCallback: Function;
+ const constructorZone: Zone = Zone.root.fork({
+ name: 'Constructor Zone',
+ onHandleError: (delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: Error) => {
+ log.push('error' + error.message);
+ const result = delegate.handleError(targetZone, error);
+ errorCallback && errorCallback();
+ return false;
+ }
+ });
+
+ beforeEach(() => {
+ log = [];
+ });
+
+ it('scheduler asap error should run in correct zone', asyncTest((done: any) => {
+ let observable: any;
+ constructorZone.run(() => {
+ observable = Rx.Observable.of(1, 2, 3).observeOn(Rx.Scheduler.asap);
+ });
+
+ errorCallback = () => {
+ expect(log).toEqual(['erroroops']);
+ setTimeout(done, 0);
+ };
+
+ Zone.root.run(() => {
+ observable
+ .map((value: number) => {
+ if (value === 3) {
+ throw new Error('oops');
+ }
+ return value;
+ })
+ .subscribe((value: number) => {});
+ });
+ }, Zone.root));
+});
\ No newline at end of file
diff --git a/test/rxjs/rxjs.spec.ts b/test/rxjs/rxjs.spec.ts
index 0515a3ffd..8a42b0fe2 100644
--- a/test/rxjs/rxjs.spec.ts
+++ b/test/rxjs/rxjs.spec.ts
@@ -7,6 +7,7 @@
*/
import '../../lib/rxjs/rxjs';
import './rxjs.common.spec';
+import './rxjs.asap.spec';
import './rxjs.bindCallback.spec';
import './rxjs.bindNodeCallback.spec';
import './rxjs.combineLatest.spec';