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

Commit 643f2ac

Browse files
committed
feat(bindPromiseFn): add bindPromiseFn method
Closes #49
1 parent fb338b6 commit 643f2ac

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed

Diff for: karma.conf.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ module.exports = function (config) {
44
config.set({
55
basePath: '',
66
files: [
7+
'test/util.js',
78
'zone.js',
89
'*-zone.js',
910
//'test/lib/brick.js',
10-
'test/util.js',
1111
'test/**/*.spec.js',
1212
{pattern: 'test/assets/**/*.html', watched: true, served: true, included: false}
1313
],

Diff for: test/util.js

+3
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ function ifEnvSupports(test, block) {
2121
}
2222
};
2323
};
24+
25+
// useful for testing mocks
26+
window.__setTimeout = window.setTimeout;

Diff for: test/zone.spec.js

+26
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,32 @@ describe('Zone', function () {
140140
});
141141
});
142142

143+
describe('bindPromiseFn', function () {
144+
var mockPromise = function() {
145+
return {
146+
then: function (a, b) {
147+
window.__setTimeout(a, 0);
148+
return mockPromise();
149+
}
150+
};
151+
};
152+
153+
it('should return a method that returns promises that run in the correct zone', function (done) {
154+
zone.fork({ mark: 'a' }).run(function () {
155+
var patched = Zone.bindPromiseFn(function() {
156+
return mockPromise();
157+
});
158+
159+
patched().then(function () {
160+
expect(zone.mark).toBe('a');
161+
}).then(function () {
162+
expect(zone.mark).toBe('a');
163+
done();
164+
});
165+
});
166+
});
167+
});
168+
143169
});
144170

145171
function throwError () {

Diff for: zone.js

+46
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,52 @@ Zone.bindArgumentsOnce = function (args) {
221221
return args;
222222
};
223223

224+
/*
225+
* patch a fn that returns a promise
226+
*/
227+
Zone.bindPromiseFn = (function() {
228+
// if the browser natively supports Promises, we can just return a native promise
229+
if (window.Promise) {
230+
return function (delegate) {
231+
return function() {
232+
var delegatePromise = delegate.apply(this, arguments);
233+
if (delegatePromise instanceof Promise) {
234+
return delegatePromise;
235+
} else {
236+
return new Promise(function(resolve, reject) {
237+
delegatePromise.then(resolve, reject);
238+
});
239+
}
240+
};
241+
};
242+
} else {
243+
// if the browser does not have native promises, we have to patch each promise instance
244+
return function (delegate) {
245+
return function () {
246+
return patchThenable(delegate.apply(this, arguments));
247+
};
248+
};
249+
250+
function patchThenable(thenable) {
251+
var then = thenable.then;
252+
thenable.then = function () {
253+
var args = Zone.bindArguments(arguments);
254+
var nextThenable = then.apply(thenable, args);
255+
return patchThenable(nextThenable);
256+
};
257+
258+
var ocatch = thenable.catch;
259+
thenable.catch = function () {
260+
var args = Zone.bindArguments(arguments);
261+
var nextThenable = ocatch.apply(thenable, args);
262+
return patchThenable(nextThenable);
263+
};
264+
return thenable;
265+
}
266+
}
267+
}());
268+
269+
224270
Zone.patchableFn = function (obj, fnNames) {
225271
fnNames.forEach(function (name) {
226272
var delegate = obj[name];

0 commit comments

Comments
 (0)