-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
39 lines (37 loc) · 1.24 KB
/
index.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
'use strict';
//
const arity = function(n, f) {
const params = Array(n + 1).join('x').replace(/x/g, function(_, n) {
return n === 0 ? '$0' : ', $' + n;
});
return Function( // jshint ignore:line
'f',
'return function(' + params + ') { return f.apply(this, arguments); }'
).call(this, f);
};
// co :: (Generator (arguments -> a)) -> (arguments -> Promise a)
// Accepts a generator function which yields promises and converts it to
// a promise-resolving state machine. Yielded promises are chained together
// using .then, rejected errors are thrown through the generator, and a
// returned value is resolved as the settled value of the promise.
exports.co = function(generator) {
const generator_length = generator.length;
return arity(generator_length, () => {
const coroutine = generator.apply(null, arguments);
return new Promise((resolve, reject) => {
const go = (method, value) => {
try {
const result = coroutine[method](value);
if (result.done) {
resolve(result.value);
} else {
result.value.then(v => go('next', v), e => go('throw', e));
}
} catch (error) {
reject(error);
}
};
go('next', null);
});
});
};