Galerie und tage
This commit is contained in:
294
node_modules/co/index.js
generated
vendored
Normal file
294
node_modules/co/index.js
generated
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
|
||||
/**
|
||||
* slice() reference.
|
||||
*/
|
||||
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
/**
|
||||
* Expose `co`.
|
||||
*/
|
||||
|
||||
module.exports = co;
|
||||
|
||||
/**
|
||||
* Wrap the given generator `fn` and
|
||||
* return a thunk.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function co(fn) {
|
||||
var isGenFun = isGeneratorFunction(fn);
|
||||
|
||||
return function (done) {
|
||||
var ctx = this;
|
||||
|
||||
// in toThunk() below we invoke co()
|
||||
// with a generator, so optimize for
|
||||
// this case
|
||||
var gen = fn;
|
||||
|
||||
// we only need to parse the arguments
|
||||
// if gen is a generator function.
|
||||
if (isGenFun) {
|
||||
var args = slice.call(arguments), len = args.length;
|
||||
var hasCallback = len && 'function' == typeof args[len - 1];
|
||||
done = hasCallback ? args.pop() : error;
|
||||
gen = fn.apply(this, args);
|
||||
} else {
|
||||
done = done || error;
|
||||
}
|
||||
|
||||
next();
|
||||
|
||||
// #92
|
||||
// wrap the callback in a setImmediate
|
||||
// so that any of its errors aren't caught by `co`
|
||||
function exit(err, res) {
|
||||
setImmediate(function(){
|
||||
done.call(ctx, err, res);
|
||||
});
|
||||
}
|
||||
|
||||
function next(err, res) {
|
||||
var ret;
|
||||
|
||||
// multiple args
|
||||
if (arguments.length > 2) res = slice.call(arguments, 1);
|
||||
|
||||
// error
|
||||
if (err) {
|
||||
try {
|
||||
ret = gen.throw(err);
|
||||
} catch (e) {
|
||||
return exit(e);
|
||||
}
|
||||
}
|
||||
|
||||
// ok
|
||||
if (!err) {
|
||||
try {
|
||||
ret = gen.next(res);
|
||||
} catch (e) {
|
||||
return exit(e);
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
if (ret.done) return exit(null, ret.value);
|
||||
|
||||
// normalize
|
||||
ret.value = toThunk(ret.value, ctx);
|
||||
|
||||
// run
|
||||
if ('function' == typeof ret.value) {
|
||||
var called = false;
|
||||
try {
|
||||
ret.value.call(ctx, function(){
|
||||
if (called) return;
|
||||
called = true;
|
||||
next.apply(ctx, arguments);
|
||||
});
|
||||
} catch (e) {
|
||||
setImmediate(function(){
|
||||
if (called) return;
|
||||
called = true;
|
||||
next(e);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// invalid
|
||||
next(new TypeError('You may only yield a function, promise, generator, array, or object, '
|
||||
+ 'but the following was passed: "' + String(ret.value) + '"'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert `obj` into a normalized thunk.
|
||||
*
|
||||
* @param {Mixed} obj
|
||||
* @param {Mixed} ctx
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function toThunk(obj, ctx) {
|
||||
|
||||
if (isGeneratorFunction(obj)) {
|
||||
return co(obj.call(ctx));
|
||||
}
|
||||
|
||||
if (isGenerator(obj)) {
|
||||
return co(obj);
|
||||
}
|
||||
|
||||
if (isPromise(obj)) {
|
||||
return promiseToThunk(obj);
|
||||
}
|
||||
|
||||
if ('function' == typeof obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (isObject(obj) || Array.isArray(obj)) {
|
||||
return objectToThunk.call(ctx, obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object of yieldables to a thunk.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function objectToThunk(obj){
|
||||
var ctx = this;
|
||||
var isArray = Array.isArray(obj);
|
||||
|
||||
return function(done){
|
||||
var keys = Object.keys(obj);
|
||||
var pending = keys.length;
|
||||
var results = isArray
|
||||
? new Array(pending) // predefine the array length
|
||||
: new obj.constructor();
|
||||
var finished;
|
||||
|
||||
if (!pending) {
|
||||
setImmediate(function(){
|
||||
done(null, results)
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// prepopulate object keys to preserve key ordering
|
||||
if (!isArray) {
|
||||
for (var i = 0; i < pending; i++) {
|
||||
results[keys[i]] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
run(obj[keys[i]], keys[i]);
|
||||
}
|
||||
|
||||
function run(fn, key) {
|
||||
if (finished) return;
|
||||
try {
|
||||
fn = toThunk(fn, ctx);
|
||||
|
||||
if ('function' != typeof fn) {
|
||||
results[key] = fn;
|
||||
return --pending || done(null, results);
|
||||
}
|
||||
|
||||
fn.call(ctx, function(err, res){
|
||||
if (finished) return;
|
||||
|
||||
if (err) {
|
||||
finished = true;
|
||||
return done(err);
|
||||
}
|
||||
|
||||
results[key] = res;
|
||||
--pending || done(null, results);
|
||||
});
|
||||
} catch (err) {
|
||||
finished = true;
|
||||
done(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert `promise` to a thunk.
|
||||
*
|
||||
* @param {Object} promise
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function promiseToThunk(promise) {
|
||||
return function(fn){
|
||||
promise.then(function(res) {
|
||||
fn(null, res);
|
||||
}, fn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if `obj` is a promise.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function isPromise(obj) {
|
||||
return obj && 'function' == typeof obj.then;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if `obj` is a generator.
|
||||
*
|
||||
* @param {Mixed} obj
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function isGenerator(obj) {
|
||||
return obj && 'function' == typeof obj.next && 'function' == typeof obj.throw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if `obj` is a generator function.
|
||||
*
|
||||
* @param {Mixed} obj
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function isGeneratorFunction(obj) {
|
||||
return obj && obj.constructor && 'GeneratorFunction' == obj.constructor.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for plain object.
|
||||
*
|
||||
* @param {Mixed} val
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function isObject(val) {
|
||||
return val && Object == val.constructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw `err` in a new stack.
|
||||
*
|
||||
* This is used when co() is invoked
|
||||
* without supplying a callback, which
|
||||
* should only be for demonstrational
|
||||
* purposes.
|
||||
*
|
||||
* @param {Error} err
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function error(err) {
|
||||
if (!err) return;
|
||||
setImmediate(function(){
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user