How to iterate over database in NodeJS? - example

node v10.24.1
version: master
endpointsharetweet
This is working example of async iteration in NodeJS used to iterate over database using range query. First we setup mock database with list of potentially habitable exoplanets. After this block there will be Database class avaliable in scope.
/** * Simple database mock * Data from https://en.wikipedia.org/wiki/List_of_potentially_habitable_exoplanets */ const exoplanets = [ {"id": 1, "object":"Proxima Centauri b","star":"Proxima Centauri","starType":"M6Ve","distance":4.22}, {"id": 2, "object":"Gliese 667 Cc","star":"Gliese 667 C", "starType":"M3V","distance":23.62}, {"id": 5, "object":"Kepler-442b","star":"Kepler-442","starType":"K?V","distance":1291.6}, {"id": 7, "object":"Kepler-452b","star":"Kepler-452","starType":"G2V","distance":1402}, {"id": 9, "object":"Wolf 1061c","star":"Wolf 1061","starType":"M3V","distance":13.8}, {"id": 11, "object":"Kepler-1229b","star":"Kepler-1229","starType":"M?V","distance":769}, {"id": 12, "object":"Kapteyn b","star":"Kapteyn","starType":"sdM1","distance":13}, {"id": 14, "object":"Kepler-62f","star":"Kepler-62","starType":"K2V","distance":1200}, {"id": 15, "object":"Kepler-186f","star":"Kepler-186","starType":"M1V","distance":561}, {"id": 16, "object":"Luyten b","star":"Luyten's Star","starType":"M3.5V","distance":12.36}, {"id": 17, "object":"TRAPPIST-1d","star":"TRAPPIST-1","starType":"M8V","distance":39}, {"id": 18, "object":"TRAPPIST-1e","star":"TRAPPIST-1","starType":"M8V","distance":39}, {"id": 20, "object":"TRAPPIST-1f","star":"TRAPPIST-1","starType":"M8V","distance":39}, {"id": 21, "object":"TRAPPIST-1g","star":"TRAPPIST-1","starType":"M8V","distance":39}, {"id": 22, "object":"LHS 1140 b","star":"LHS 1140","starType":"M?V","distance":40}, {"id": 24, "object":"Kepler-1638b","star":"Kepler-1638","starType":"G4V","distance":2491.83}, {"id": 25, "object":"Teegarden c*","star":"Teegarden's Star","starType":"M7V","distance":12.58} ]; /** * This is our database mock */ class Database { constructor() { this.data = exoplanets; } log(idGreaterThan, limit) { let wheresql = idGreaterThan ? ` WHERE id > ${idGreaterThan}` : ''; let limitsql = limit < Infinity ? ` LIMIT ${limit}` : ''; console.info(`DATABASE: SELECT * FROM exoplanets${wheresql} ORDER BY id ASC${limitsql}`); } /** * Select planets with id grater than idGreaterThan * @param {object} query * @param {number} query.idGreaterThan boundrary value of id * @param {number} query.limit limit of rows * @returns {Promise<Array>} list of planets */ async select(query) { const { idGreaterThan, limit } = { idGreaterThan: 0, limit: Infinity, ...query }; this.log(idGreaterThan, limit); const reply = []; for(let item of this.data) { if(item.id > idGreaterThan) { reply.push(item); } if(reply.length === limit) { break; } } return reply; } } /** * Just wait 3s */ function wait() { return new Promise((resolve) => { setTimeout(resolve, 3000); }); }
Next create function generator to iterate over database.
/** * Iterate over database * @generator * @function readDocuments * @param {number} limit maximum number of documents * @yields {array} list of planets */ async function* readDocuments(limit) { const db = new Database(); let lastId = 0; // initialize with min value let done = false; // indicates end of iteration while(!done) { // select batch of documents and wait for database response // TODO: error handling const result = await db.select({ idGreaterThan: lastId, limit: limit }); // get id of last document lastId = result[result.length - 1].id; // end iteration if there are less documents than limit if(result.length < limit) { done = true; } // yield result yield result } };
Use for-loop to iterate over dataset. In this example I use IIFE to take advantage of async-await.
(async function run() { // Iterate over dataset for await(let documents of readDocuments(4)) { // Do something with planets const planets = documents.map(planet => planet.object).join(', '); console.info(`APP: Got ${documents.length} items from database: ${planets}`); await wait(); } })();
Loading…

no comments

    sign in to comment