-
Notifications
You must be signed in to change notification settings - Fork 11
/
makeAsync.js
96 lines (83 loc) · 2.28 KB
/
makeAsync.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module.exports = (function () {
"use strict";
// Author: Matthew Forrester <matt_at_keyboardwritescode.com>
// Copyright: Matthew Forrester
// License: MIT/BSD-style
/**
* # makeAsync(classFunc, asynchronousDelay)
*
* Takes a pseudo-classical Javascript class and converts that class into an
* asynchronous version.
*
* ## Example
* ```javascript
* var MyClass = function(property) {
* this.property = property;
* };
*
* MyClass.prototype.getProperty = function() {
* return this.property + 3;
* };
*
* var AsyncMyClass = makeAsync(MyClass);
* var asyncMyClass = new AsyncMyClass(4);
* asyncMyClass.getProperty(function(property) {
* // Outputs "Property is 7"
* console.log('Property is '+property);
* });
* ```
*
* ## Parameters
* * **@param {Function} `classFunc`**
* * **@param {Number} `asynchronousDelay`**
*/
return function(classFunc,asynchronousDelay,nodeStyle) {
// This will create the constructor
var constructorFunc = function() {
var args = Array.prototype.slice.call(arguments);
args.unshift(null);
var Factory = classFunc.bind.apply(
classFunc,
args
);
this._inst = new Factory();
};
var k = '';
// Takes a function and a factor and returns an asynchronous
// (if factor != false) function which wraps the func and passes
// it's parameters through with the addition of a callback
var makeLaggy = function(func,factor) {
return function() {
/* globals setTimeout: false */
var args = Array.prototype.slice.call(arguments),
cb;
while (typeof args.slice(-1)[0] === 'function') {
cb = args.pop();
}
if (factor === false) {
return cb(func.apply(this._inst,args));
}
setTimeout(function() {
var r = [func.apply(this._inst,args)];
if (nodeStyle) {
r.unshift(null);
}
cb.apply(this, r);
}.bind(this),Math.floor(Math.random() * factor) + 1);
};
};
// This should be an IIFE in the for loop below, except that JSHint complains
// about functions in loops
var proc = function(k) {
constructorFunc.prototype[k] = makeLaggy(classFunc.prototype[k],asynchronousDelay);
};
// Look at classFunc and use makeLaggy to attach a asynchronous version of
// the function.
for (k in classFunc.prototype) {
if (classFunc.prototype.hasOwnProperty(k)) {
proc(k);
}
}
return constructorFunc;
};
}());