Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit e90479a

Browse files
committed
refactor, not create a new closure _subscribe everytime
1 parent 7f3d467 commit e90479a

File tree

5 files changed

+62
-48
lines changed

5 files changed

+62
-48
lines changed

Diff for: karma-build.conf.js

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ module.exports = function (config) {
1313
config.files.push('build/lib/zone.js');
1414
config.files.push('build/lib/common/promise.js');
1515
config.files.push('build/lib/common/error-rewrite.js');
16+
config.files.push('build/lib/rxjs/rxjs.js');
1617
config.files.push('build/test/main.js');
1718
};

Diff for: karma-dist.conf.js

+1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ module.exports = function (config) {
1818
config.files.push('dist/sync-test.js');
1919
config.files.push('dist/task-tracking.js');
2020
config.files.push('dist/wtf.js');
21+
config.files.push('dist/zone-patch-rxjs.js');
2122
config.files.push('build/test/main.js');
2223
};

Diff for: lib/rxjs/rxjs.ts

+56-43
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ declare let define: any;
1919
}
2020
}(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global,
2121
(Rx: any) => {
22+
'use strict';
2223
Zone.__load_patch('rxjs', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
2324
const subscribeSource = 'rxjs.subscribe';
2425
const nextSource = 'rxjs.Subscriber.next';
@@ -33,6 +34,14 @@ declare let define: any;
3334
Rx.Observable = function() {
3435
Observable.apply(this, arguments);
3536
this._zone = Zone.current;
37+
38+
// patch inner function this._subscribe to check
39+
// SubscriptionZone is same with ConstuctorZone or not
40+
if (this._subscribe && typeof this._subscribe === 'function' && !this._originalSubscribe) {
41+
this._originalSubscribe = this._subscribe;
42+
this._subscribe = _patchedSubscribe;
43+
}
44+
3645
return this;
3746
};
3847

@@ -42,6 +51,39 @@ declare let define: any;
4251
const lift = Observable.prototype.lift;
4352
const create = Observable.create;
4453

54+
const _patchedSubscribe = function() {
55+
const currentZone = Zone.current;
56+
const _zone = this._zone;
57+
58+
const args = Array.prototype.slice.call(arguments);
59+
const subscriber = args.length > 0 ? args[0] : undefined;
60+
// also keep currentZone in Subscriber
61+
// for later Subscriber.next/error/complete method
62+
if (subscriber && !subscriber._zone) {
63+
subscriber._zone = currentZone;
64+
}
65+
// _subscribe should run in ConstructorZone
66+
// but for performance concern, we should check
67+
// whether ConsturctorZone === Zone.current here
68+
const tearDownLogic = _zone !== Zone.current ?
69+
_zone.run(this._originalSubscribe, this, args) :
70+
this._originalSubscribe.apply(this, args);
71+
if (tearDownLogic && typeof tearDownLogic === 'function') {
72+
const patchedTearDownLogic = function() {
73+
// tearDownLogic should also run in ConstructorZone
74+
// but for performance concern, we should check
75+
// whether ConsturctorZone === Zone.current here
76+
if (_zone && _zone !== Zone.current) {
77+
return _zone.run(tearDownLogic, this, arguments);
78+
} else {
79+
return tearDownLogic.apply(this, arguments);
80+
}
81+
};
82+
return patchedTearDownLogic;
83+
}
84+
return tearDownLogic;
85+
};
86+
4587
// patch Observable.prototype.subscribe
4688
// if SubscripitionZone is different with ConstructorZone
4789
// we should run _subscribe in ConstructorZone and
@@ -51,43 +93,6 @@ declare let define: any;
5193
const _zone = this._zone;
5294
const currentZone = Zone.current;
5395

54-
// patch inner function this._subscribe to check
55-
// SubscriptionZone is same with ConstuctorZone or not
56-
if (this._subscribe && typeof this._subscribe === 'function') {
57-
this._subscribe._zone = this._zone;
58-
const _subscribe = this._subscribe;
59-
if (_zone) {
60-
this._subscribe = function() {
61-
const args = Array.prototype.slice.call(arguments);
62-
const subscriber = args.length > 0 ? args[0] : undefined;
63-
// also keep currentZone in Subscriber
64-
// for later Subscriber.next/error/complete method
65-
if (subscriber && !subscriber._zone) {
66-
subscriber._zone = currentZone;
67-
}
68-
// _subscribe should run in ConstructorZone
69-
// but for performance concern, we should check
70-
// whether ConsturctorZone === Zone.current here
71-
const tearDownLogic = _zone !== Zone.current ? _zone.run(_subscribe, this, args) :
72-
_subscribe.apply(this, args);
73-
if (tearDownLogic && typeof tearDownLogic === 'function') {
74-
const patchedTearDownLogic = function() {
75-
// tearDownLogic should also run in ConstructorZone
76-
// but for performance concern, we should check
77-
// whether ConsturctorZone === Zone.current here
78-
if (_zone && _zone !== Zone.current) {
79-
return _zone.run(tearDownLogic, this, arguments);
80-
} else {
81-
return tearDownLogic.apply(this, arguments);
82-
}
83-
};
84-
return patchedTearDownLogic;
85-
}
86-
return tearDownLogic;
87-
};
88-
}
89-
}
90-
9196
// if operator is involved, we should also
9297
// patch the call method to save the Subscription zone
9398
if (this.operator && _zone && _zone !== currentZone) {
@@ -102,12 +107,6 @@ declare let define: any;
102107
};
103108
}
104109
const result = subscribe.apply(this, arguments);
105-
// clean up _subscribe._zone to prevent
106-
// the same _subscribe being used in multiple
107-
// Observable instances.
108-
if (this._subscribe) {
109-
this._subscribe._zone = undefined;
110-
}
111110
// the result is the subscriber sink,
112111
// we save the current Zone here
113112
result._zone = currentZone;
@@ -118,13 +117,27 @@ declare let define: any;
118117
Observable.prototype.lift = function() {
119118
const observable = lift.apply(this, arguments);
120119
observable._zone = Zone.current;
120+
// patch inner function this._subscribe to check
121+
// SubscriptionZone is same with ConstuctorZone or not
122+
if (this._subscribe && typeof this._subscribe === 'function' && !this._originalSubscribe) {
123+
this._originalSubscribe = this._subscribe;
124+
this._subscribe = _patchedSubscribe;
125+
}
126+
121127
return observable;
122128
};
123129

124130
// patch create method to save ConstructorZone of Observable
125131
Rx.Observable.create = function() {
126132
const observable = create.apply(this, arguments);
127133
observable._zone = Zone.current;
134+
// patch inner function this._subscribe to check
135+
// SubscriptionZone is same with ConstuctorZone or not
136+
if (this._subscribe && typeof this._subscribe === 'function' && !this._originalSubscribe) {
137+
this._originalSubscribe = this._subscribe;
138+
this._subscribe = _patchedSubscribe;
139+
}
140+
128141
return observable;
129142
};
130143

Diff for: test/browser-zone-setup.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,4 @@ import '../lib/zone-spec/proxy';
1717
import '../lib/zone-spec/sync-test';
1818
import '../lib/zone-spec/task-tracking';
1919
import '../lib/zone-spec/wtf';
20-
import '../lib/extra/cordova';
21-
import '../lib/rxjs/rxjs';
20+
import '../lib/extra/cordova';

Diff for: test/rxjs/rxjs.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
*/
88

99
let rxjs;
10-
if (typeof exports === 'object') {
11-
rxjs = require('rxjs');
12-
} else {
10+
if (typeof window !== 'undefined') {
1311
rxjs = (window as any).Rx;
12+
} else if (typeof exports === 'object' && typeof module !== undefined) {
13+
rxjs = require('rxjs');
1414
}
1515
const Observable = rxjs.Observable;
1616
const Subscriber = rxjs.Subscriber;

0 commit comments

Comments
 (0)