Skip to content

Commit 02b7092

Browse files
committed
Adds the ability to require()
This makes it possible to import both other scripts, as well as single functions (both named and anonymous) into the worker. A path to a script given to require() is relative to the worker. This means we have to use eval.js in order to have a fixed path to use as a reference.
1 parent 3eeebd2 commit 02b7092

File tree

3 files changed

+104
-6
lines changed

3 files changed

+104
-6
lines changed

lib/parallel.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,39 @@
7777
this.options = extend(defaults, options);
7878
this.operation = new Operation();
7979
this.operation.resolve(null, this.data);
80+
this.requiredScripts = [];
81+
this.requiredFunctions = [];
8082
}
8183

8284
Parallel.prototype.getWorkerSource = function (cb) {
85+
var preStr = '';
86+
var i = 0;
87+
if (!isNode && this.requiredScripts.length !== 0) {
88+
preStr += 'importScripts("' + this.requiredScripts.join('","') + '");\r\n';
89+
}
90+
91+
for (i = 0; i < this.requiredFunctions.length; ++i) {
92+
if (this.requiredFunctions[i].name) {
93+
preStr += 'var ' + this.requiredFunctions[i].name + ' = ' + this.requiredFunctions[i].fn.toString() + ';';
94+
} else {
95+
preStr += this.requiredFunctions[i].fn.toString();
96+
}
97+
}
98+
8399
if (isNode) {
84-
return 'process.on("message", function(e) {process.send(JSON.stringify((' + cb.toString() + ')(JSON.parse(e).data)))})';
100+
return preStr + 'process.on("message", function(e) {process.send(JSON.stringify((' + cb.toString() + ')(JSON.parse(e).data)))})';
85101
} else {
86-
return 'self.onmessage = function(e) {self.postMessage((' + cb.toString() + ')(e.data))}';
102+
return preStr + 'self.onmessage = function(e) {self.postMessage((' + cb.toString() + ')(e.data))}';
103+
}
104+
};
105+
106+
Parallel.prototype.require = function (func) {
107+
if (typeof func === 'string') {
108+
this.requiredScripts[this.requiredScripts.length] = func;
109+
} else if (typeof func === 'function') {
110+
this.requiredFunctions[this.requiredFunctions.length] = { fn: func };
111+
} else if (typeof func === 'object') {
112+
this.requiredFunctions[this.requiredFunctions.length] = func;
87113
}
88114
};
89115

@@ -95,10 +121,19 @@
95121
wrk.postMessage(src);
96122
} else {
97123
try {
98-
var blob = new Blob([src], { type: 'text/javascript' });
99-
var url = URL.createObjectURL(blob);
124+
if (this.requiredScripts.length !== 0) {
125+
if (this.options.ie10shim) {
126+
wrk = new Worker(this.options.path);
127+
wrk.postMessage(src);
128+
} else {
129+
throw new Error('Can\'t use required scripts without eval.js!');
130+
}
131+
} else {
132+
var blob = new Blob([src], { type: 'text/javascript' });
133+
var url = URL.createObjectURL(blob);
100134

101-
wrk = new Worker(url);
135+
wrk = new Worker(url);
136+
}
102137
} catch (e) {
103138
if (this.options.ie10shim) { // blob/url unsupported, cross-origin error
104139
wrk = new Worker(this.options.path);

test/api.spec.js

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
expect(p.map).toEqual(jasmine.any(Function));
1717
});
1818

19+
it('should define a require(string|function|{ name: string, fn: function }) function', function () {
20+
var p = new Parallel([1, 2, 3]);
21+
expect(p.require).toEqual(jasmine.any(Function));
22+
});
23+
1924
it('should execute a .then function without an operation immediately', function () {
2025
var p = new Parallel([1, 2, 3]);
2126
expect(p.then).toEqual(jasmine.any(Function));
@@ -80,7 +85,7 @@
8085
});
8186

8287
it('should queue map work correctly', function () {
83-
var p = new Parallel([1, 2, 3], {maxWorkers: 2});
88+
var p = new Parallel([1, 2, 3], { maxWorkers: 2 });
8489

8590
var done = false;
8691
var result = null;
@@ -211,4 +216,59 @@
211216
expect(result).toEqual(9);
212217
});
213218
});
219+
220+
if (!isNode) {
221+
it('should work with require()d scripts (web-exclusive)', function () {
222+
var p = new Parallel([1, 2, 3]);
223+
p.require('../test/test.js'); // relative to eval.js
224+
225+
var done = false;
226+
var result = null;
227+
228+
runs(function () {
229+
p.map(function (el) {
230+
return myCalc(el, 25);
231+
}).then(function (data) {
232+
result = data;
233+
done = true;
234+
});
235+
});
236+
237+
waitsFor(function () {
238+
return done;
239+
}, "it should finish", 500);
240+
241+
runs(function () {
242+
expect(result).toEqual([26, 27, 28]);
243+
});
244+
});
245+
}
246+
247+
it('should work with require()d anonymous functions', function () {
248+
var fn = function (el, amount) {
249+
return el + amount;
250+
};
251+
var p = new Parallel([1, 2, 3]);
252+
p.require({ name: 'fn', fn: fn });
253+
254+
var done = false;
255+
var result = null;
256+
257+
runs(function () {
258+
p.map(function (el) {
259+
return fn(el, 25);
260+
}).then(function (data) {
261+
result = data;
262+
done = true;
263+
});
264+
});
265+
266+
waitsFor(function () {
267+
return done;
268+
}, "it should finish", 500);
269+
270+
runs(function () {
271+
expect(result).toEqual([26, 27, 28]);
272+
});
273+
});
214274
});

test/test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function myCalc(el, amount) {
2+
return el + amount;
3+
}

0 commit comments

Comments
 (0)