Created
December 4, 2016 05:12
-
-
Save benjie/2b98bbbb14bcb07207c468316b3ee097 to your computer and use it in GitHub Desktop.
A monoclejs-like purely promise based asynchronous generator iterator thingy (where you can relatively safely sprinkle `yield` everywhere)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function isIterator(obj) { | |
return (obj && typeof obj === 'object' && typeof obj.next === 'function' && typeof obj.throw === 'function'); | |
} | |
function isPromise(obj) { | |
return (obj && typeof obj === 'object' && typeof obj.then === 'function'); | |
} | |
function o_P() { | |
var _resolve, _reject; | |
var promise = new Promise(function (resolve, reject) { | |
_resolve = resolve; | |
_reject = reject; | |
}); | |
promise._resolve = _resolve; | |
promise._reject = _reject; | |
return promise; | |
} | |
function o_R(iterator, promise, toGenErr, toGenVal) { | |
var iteratorResult; | |
if (!promise) { | |
promise = o_P(); | |
} | |
for (;;) { | |
try { | |
if (toGenErr) { | |
iteratorResult = iterator.throw(toGenErr); | |
} else { | |
iteratorResult = iterator.next(toGenVal); | |
} | |
} catch (e) { | |
promise._reject(e); | |
return promise; | |
} | |
var value = iteratorResult.value; | |
if (iteratorResult.done) { | |
promise._resolve(value); | |
return promise; | |
} | |
var nextPromise; | |
if (isPromise(value)) { | |
nextPromise = value; | |
} else if (isIterator(value)) { | |
nextPromise = o_R(value); | |
} else { | |
toGenErr = undefined; | |
toGenVal = value; | |
} | |
if (nextPromise) { | |
nextPromise.then( | |
function(nextValue) {return o_R(iterator, promise, undefined, nextValue)}, | |
function(err) {o_R(iterator, promise, err, undefined);} | |
); | |
return promise; | |
} | |
} | |
return promise; | |
} | |
function o_O(generator) { | |
var fn = function() { | |
var result; | |
try { | |
result = generator.apply(this, Array.prototype.slice.call(arguments)); | |
} catch (e) { | |
return Promise.reject(e); | |
} | |
if (isIterator(result)) { | |
return o_R(result); | |
} | |
return Promise.resolve(result); | |
} | |
return fn; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment