Created
April 25, 2017 10:44
-
-
Save damirka/ec46329157878fd5c688af8aa23a6225 to your computer and use it in GitHub Desktop.
Using generators to execute async code in a sync manner
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
'use strict'; | |
const EventEmitter = require('events'); | |
/** | |
* Runs generator and puts EventEmitter context in it to let user | |
* emit any events inside generator and subscribe to them from outside. | |
* | |
* @param {Function} gen Function which returns generator | |
* @return {EventEmitter} Returns emitter instance which is bound | |
*/ | |
function runGenerator(gen) { | |
let res; | |
let emitter = new EventEmitter(); | |
let iterator = gen.call(emitter); | |
(function iterate(value) { | |
res = iterator.next(value); | |
if (!res.done) { | |
return (res.value instanceof Promise) | |
? res.value.then((value) => iterate(value)) | |
: setImmediate(() => iterate(res.value)); | |
} | |
})(); | |
return emitter; | |
} | |
// EXAMPLE | |
const Pool = require('pg').Pool; | |
const Cursor = require('pg-cursor'); | |
const pool = new Pool(); | |
let it = runGenerator(function* () { | |
let chunk = 2; | |
let sql = 'SELECT * FROM generate_series(0, 9, 1)'; | |
let client = yield pool.connect(); | |
let cursor = yield client.query(new Cursor(sql)); | |
let data; | |
this.emit('init'); | |
while (data !== null) { | |
data = yield new Promise((resolve) => { | |
cursor.read(chunk, (err, rows) => resolve(rows.length ? rows : null)); | |
}); | |
if (data !== null) { | |
this.emit('data', data); | |
} | |
} | |
yield client.release(); | |
this.emit('end'); | |
}); | |
it.on('init', () => console.log('connection established')); | |
it.on('data', (data) => { | |
// ... do anything with data ... | |
}); | |
it.on('end', () => console.log('client released')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment