workerize.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. var restArgs = require('./restArgs');
  2. var uniqId = require('./uniqId');
  3. var toSrc = require('./toSrc');
  4. var createUrl = require('./createUrl');
  5. var isStr = require('./isStr');
  6. var root = require('./root');
  7. exports = function(fn) {
  8. var promises = {};
  9. var src = [
  10. toSrc(isPromise),
  11. 'onmessage=(',
  12. toSrc(function(fn) {
  13. return function(e) {
  14. var data = e.data;
  15. var id = data[0];
  16. var args = data[1];
  17. var value;
  18. try {
  19. value = fn.apply(fn, args);
  20. if (isPromise(value)) {
  21. value.then(
  22. function(value) {
  23. postMessage([id, null, value]);
  24. },
  25. function(err) {
  26. postMessage([id, err.message]);
  27. }
  28. );
  29. } else {
  30. postMessage([id, null, value]);
  31. }
  32. } catch (e) {
  33. postMessage([id, e.message]);
  34. }
  35. };
  36. }),
  37. ')(' + toSrc(fn) + ')'
  38. ].join('\n');
  39. var worker = new Worker(createUrl(src));
  40. worker.onmessage = function(e) {
  41. var data = e.data;
  42. var id = data[0];
  43. var err = data[1];
  44. var value = data[2];
  45. if (isStr(err)) err = new Error(err);
  46. promises[id](err, value);
  47. delete promises[id];
  48. };
  49. return restArgs(function(args) {
  50. var id = uniqId('workerize');
  51. return new root.Promise(function(resolve, reject) {
  52. promises[id] = function(err, value) {
  53. if (err) return reject(err);
  54. resolve(value);
  55. };
  56. worker.postMessage([id, args]);
  57. });
  58. });
  59. };
  60. function isPromise(val) {
  61. return (
  62. !!val &&
  63. (typeof val === 'object' || typeof val === 'function') &&
  64. typeof val.then === 'function' &&
  65. typeof val.catch === 'function'
  66. );
  67. }
  68. module.exports = exports;