Skip to content

Instantly share code, notes, and snippets.

@Jeff-Lewis
Forked from aaaristo/newer.js
Created January 27, 2016 14:28
Show Gist options
  • Save Jeff-Lewis/60e0a5311fa37d1c8090 to your computer and use it in GitHub Desktop.
Save Jeff-Lewis/60e0a5311fa37d1c8090 to your computer and use it in GitHub Desktop.
a "ThreadLocal"-like context for asynchronous callback domains
function isIterator(obj)
{
return obj&&obj.next&&obj.throw;
}
function isRunWithContext(obj)
{
return obj&&typeof obj=='function'&&obj.ctx;
}
function run(gen)
{
var ctx= {};
return new Promise(function (mainResolve,mainReject)
{
try
{
var iterator= gen(ctx);
(function iterate(iterator,element,done)
{
try
{
var promise= element.value;
if (promise instanceof Promise)
promise.then
(function (value)
{
iterate(iterator,iterator.next(value),done);
},
function (err)
{
iterate(iterator,iterator.throw(err),done);
});
else
if (isIterator(promise))
iterate(promise,promise.next(),
function (result)
{
iterate(iterator,iterator.next(result),done);
});
else
if (isRunWithContext(promise))
{
var iter= promise(ctx);
iterate(iter,iter.next(),
function (result)
{
iterate(iterator,iterator.next(result),done);
});
}
else
if (element.done)
done(element.value);
else
iterate(iterator,iterator.next(),done);
}
catch (ex)
{
mainReject(ex);
}
})(iterator,iterator.next(),mainResolve);
}
catch (ex)
{
mainReject(ex);
}
});
}
run.withContext= function (gen)
{
gen.ctx= true;
return gen;
};
function readFile(path)
{
return new Promise(function (resolve,reject)
{
require('fs').readFile(path,function (err,buff)
{
if (err) return reject(err);
resolve(buff);
});
});
}
function* reader(n)
{
try
{
var contents= yield readFile(process.argv[2]);
console.log('here'+n,contents);
}
catch (err)
{
console.log('err'+n,err);
}
}
function readerCtx(n)
{
return run.withContext(function* (ctx)
{
console.log('readerCtx',ctx);
try
{
var contents= yield readFile(process.argv[2]);
console.log('here'+n,contents);
}
catch (err)
{
console.log('err'+n,err);
}
return contents;
});
}
run(function* (ctx)
{
try
{
var contents= yield readFile(process.argv[2]);
ctx.name= 'ciao';
console.log('here',contents);
yield reader(2);
yield reader(3);
contents= yield readerCtx(4);
console.log('out',contents);
}
catch (err)
{
console.log('err',err);
}
}).then(console.log,console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment