-
Notifications
You must be signed in to change notification settings - Fork 407
fix(rxjs): fix #863, fix asap scheduler issue, add testcases #848
Conversation
e656c1e
to
0aac91c
Compare
@mhevery , I have finished adding test cases for basically all the APIs of
Please review. |
@benlesh could you have a look? |
This is an issue as we are moving in the direction of individual tree shaking. |
One thing which is not clear to me is why do we need to batch the scheduler? Could you give me an example where non patched scheduler will do the wrong thing? |
@mhevery , about the Rx.Scheduler.asap, the following case will not work without patch. let func;
constructorZone.run(() => {
func = function(arg0: any, callback: Function) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(arg0);
};
boundFunc = Rx.Observable.bindCallback(func, null, Rx.Scheduler.asap);
observable = boundFunc('test');
});
observable.subscribe(...) Because Rx.Scheduler.asap not using |
ebbc836
to
365d195
Compare
@mhevery , I have updated the code and the now Please review. What have been patched.Below is the summarize of what have been patched.
const observable: any = constructorZone.run(() => new Rx.Observable((_subscriber: any) => {
expect(Zone.current.name).toEqual(constructorZone.name);
}));
let observable: any = constructorZone.run(() => Rx.Observable.create((subscriber: any) => {
expect(Zone.current.name).toEqual(constructorZone.name);
}));
Observable.of(1,2).map(item => {
expect(Zone.current.name).toEqual(constructorZone.name);
});
const observable: any = constructorZone.run(() => new Rx.Observable((_subscriber: any) => {
return () => {
expect(Zone.current.name).toEqual(constructorZone.name);
};
}));
import 'rxjs/add/observable/bindCallback';
import 'rxjs/add/observable/bindNodeCallback';
import 'rxjs/add/observable/defer';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/observable/fromEventPattern';
import 'rxjs/add/operator/multicast';
import {Observable} from 'rxjs/Observable';
import {asap} from 'rxjs/scheduler/asap';
import {Subscriber} from 'rxjs/Subscriber';
import {Subscription} from 'rxjs/Subscription'; those libraries. |
ca35b1d
to
b3d52ae
Compare
@mhevery , I updated again.
import {rxSubscriber} from 'rxjs/symbol/rxSubscriber'; the reason is we need this symbol to implement please review. |
test/global-rxjs.ts
Outdated
@@ -1,4 +1,5 @@ | |||
/** | |||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why do we need this file. Could you provide some insight? This file seems to just reexport things which means that it should be unnecessary? Could you explain what issue you are trying to solve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhevery , yes, you are right, in the previous version, we patch Observable constructor
, so I need this to make sure in karma dist
test run, only one rxjs
is loaded, now we don't patch Observable constructor
any longer, we don't need this one. I will remove it.
Updated
in the previous commit, I add a global-rxjs.ts
, the purpose is, in karma dist
test, the load order is
- load
node_modules/rxjs/bundles/Rx.js
, this is an umd module. - load
dist/zone-patch-rxjs.js
, this is also an umd module.
when load dist/zone-patch-rxjs.js
, it will try to import operators such as import 'rxjs/add/observable/bindCallback';
, because we use systemjs
, it will try to load rxjs/add/observable/bindCallback.js
from karma server
. So I have to map rxjs/add/observable/bindCallback
to somewhere, and make sure it use the same module as node_modules/rxjs/bundles/Rx.js
, so I map it to a global-rxjs
which only do an re-export.
I don’t know if I describe it clearly, please check it.
test/main.ts
Outdated
System.config({ | ||
defaultJSExtensions: true, | ||
map: { | ||
'rxjs/Rx': 'base/build/test/global-rxjs.js', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this? Why can't we just use standard way of loading RxJS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as above, I will remove it.
karma-base.conf.js
Outdated
@@ -13,7 +13,7 @@ module.exports = function (config) { | |||
'node_modules/systemjs/dist/system-polyfills.js', | |||
'node_modules/systemjs/dist/system.src.js', | |||
'node_modules/whatwg-fetch/fetch.js', | |||
{pattern: 'node_modules/rxjs/bundles/Rx.js', watched: true, served: true, included: false}, | |||
{pattern: 'node_modules/rxjs/bundles/Rx.js', watched: true, served: true, included: true}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we went from sytemJS loading the code to UMD. Why do we need to do this change? I think SystemJS was fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhevery , yes, the same reason with above comment, I will change it.
@mhevery , I have updated the source to remove unnecessary karma rxjs loader code , please review. ##Updated## sorry, I did not use |
fix #863.
Rx.scheduler.asap will not use
window.setImmediate
, instead it usewindow.postMessage
, and thepostMessage
eventListener is a global function which was bound when application bootup, so the function will always run in<root> zone
, in this PR, we patchasap
scheduler to run in correct zone.continue to add testcases. ( in progress)
current progress.
Patch
Observable
constructor. KeepZone.current
.So
_subscriber
which passed into constructor andtearDownLogic
will run in theZone
when create Observablepatch
operator
patch static factory method , So
_subscriber
which passed into constructor andtearDownLogic
will run in theZone
when create ObservableRx.Observable static methods.
lift
.lift
.defer
function was patched. Because the callback will be called later.forkJoin(observable, selector)
signature, theselector function also need to be called in the
Zone
it was created.addEventListener/removeEventListener
alreadybe patched by
zone.js
.addListener/removeListener
callback need to be run in the
Zone
when it was created.setInterval
already been patched.lift
._subscribe
in constructor.accept
_subscribe
in constructor.lift
.Rx.Observable.prototype methods
basically all
operator
methods, don't need to be patched, It was called bylift
.Rx.Observable.multicast methods
multicast have
subscriberFactory
, it should run in the Zone which was created.Rx.Scheduler.asap
patch asap because it not use setImmediate, it use
window.postMessage
.Rx.Observable._subscribe
have been patched to make sure subscriber callback run in the Zone when observable.subscribe was called.