Skip to content

Support for Promises/A+? #180

@jimlloyd

Description

@jimlloyd

Joe, would you consider adding support for Promises/A+ (i.e. merging a PR if I prepared one)? Currently node-java creates two javascript methods for every method of a class, an async version with the same name, and a sync version with the 'Sync' suffix. We'd like to have a third variant, which is async but returning a promise. We have used both Q and Bluebird. I believe it is possible to implement a solution that would let users of node-java choose which promises library they would use, by simply adding to the node-java API the ability to pass in a 'promisify' function.

Something along the lines of:

var java = require('java');
var asyncOptions = {
  promisify: require('q').nfbind     // or require('bluebird').promisify
  suffix: 'Promise'
};
java.setAsyncOptions(asyncOptions);
java.classpath.push(...);
...

I use 'asyncOptions' instead of 'promisesOptions' since I imagine the possibility of disabling the generation of callback-style async methods, and only using promises.

I've started inspecting the current node-java sources to figure out how to implement the change. There are some easy changes that can be made in lib/nodeJavaBridge.js, and perhaps that is the right place to promisify static methods, with code along these lines:

// copy static methods
var methods = clazz.getDeclaredMethodsSync();
for (i = 0; i < methods.length; i++) {
  if (((methods[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
    && ((methods[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
    var methodName = methods[i].getNameSync();
    result[methodName + 'Sync'] = java.callStaticMethodSync.bind(java, name, methodName);
    result[methodName] = java.callStaticMethod.bind(java, name, methodName);
    result[methodName + asyncOptions.suffix ] = asyncOptions.promisify(result[methodName]);   // Add just this one line
  }
}

Promisifying instance methods is harder. It requires knowledge of v8 and nan that I don't yet have. I see that maybe the key changes would be localized to a few lines in javaObject.cpp, in the loop across instance methods around lines 45 to 56. I can probably figure it out with more study of the documentation for v8 and nan, but I wonder if you might be able to help me out with that part?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions