Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok to initialize exports asynchronously in a node.js module?

As MongoDB database access and initialization is asynchronous on Node.js, I would like to define one module per collection that exports wrapped db calls after db initialization.

Such a "Cars.model.js" module looks like that:

var db = require("mongodb");
db.collection("cars", function(err, col) {
    exports.getCars = function(callback) {
        col.find({}, callback);
    };
});

so that other modules can run:

var carModel = require("Cars.model.js").getCars;
getCars(err, cars) {
    // (do something with cars here...)
};

It happened to me that getCars was undefined, because db access was not yet initialized at the time my second module was run.

How do you deal with creating such asynchronous db models?

like image 963
Adrien Joly Avatar asked Jun 21 '11 12:06

Adrien Joly


People also ask

Can you export async function in node JS?

Can we export async function? This is not possible. Since the value is retrieved asynchronously, all modules that consume the value must wait for the asynchronous action to complete first – this will require exporting a Promise that resolves to the value you want.

Is node JS really asynchronous?

NodeJS is an asynchronous event-driven JavaScript runtime environment designed to build scalable network applications. Asynchronous here refers to all those functions in JavaScript that are processed in the background without blocking any other request.

What is the purpose of module exports in node JS?

Module exports are the instructions that tell Node. js which bits of code (functions, objects, strings, etc.) to export from a given file so that other files are allowed to access the exported code.

Is NodeJS synchronous by default?

Asynchronous By Default. To provide concurrency, time-consuming operations (in particular I/O events and I/O callbacks) in Node. js are asynchronous by default.


1 Answers

You cannot write to exports after you've left the file. You must be blocking. To avoid being blocking I would use lazy loading of resources.

var carCol;
var carEmitter = new require("events").EventEmitter;


exports.getCars = function(callback) {
  // if no car collection then bind to event
  if (carCol === undefined) {
    carEmitter.on("cars-ready", function() {
      callback(carCol);
    });
  } else {
    // we have cars, send them back
    callback(carCol);
  }
}

db.collection("cars", function(err, col) {
  // store cars
  carCol = col;
  // tell waiters that we have cars.
  carEmitter.emit("cars-ready");
});

Use event emitters to emulate lazy loading. You may want to generalize to a LazyLoadedCollection class/object to make the code neater / more DRY.

like image 50
Raynos Avatar answered Oct 22 '22 04:10

Raynos