Github user jbmusso commented on the issue:
https://github.com/apache/tinkerpop/pull/450
I was thinking that supporting JavaScript `Promise` could be helpful now
that theyâve been part of the ES2015 and rolled out on most JS environment
(browsers/Node.js). Maybe this can be polyfilled under Nashorn? Using `Promise`
could complement Node.js style async functions with a callback passed as last
parameter (functions with such signature can be easily converted to functions
returning a Promise [with many third-party Promise libraries such as
Bluebird](http://bluebirdjs.com/docs/api/promise.promisify.html)). This way, a
`Traversal` could be ended with something like `.toPromise()`. I think the
following makes a lot of sense in JavaScript since itâs part of the standard:
```javascript
// JavaScript
g.V().out('created').toPromise()
.then(function (vertices) {
// do something with results
})
.catch(function (err) {
// handle error
})
.finally(function () {
// cleanup
});
// Alternatively, the end user could use use a promisifying function over
.toList():
g.V().out('created').toListAsync()
.then()
.catch();
```
Coming soon to the standard are `async` functions which return a `Promise`,
so you could do this:
```javascript
// JavaScript
async function followers() {
try {
const followers = await g.V().in('followers').toPromise();
} catch(e) {
// Handle error
}
}
```
There also are `Observable` (think: `Promise` with multiple return values,
or `Array` but laid out over time rather than in memory) that are worth
considering in JavaScript. Observable are candidate for being part of the
standard. Libraries such as RxJS v5, which aims to be spec. compliant, works
wonderfully. That way, we could also have `.toObservable()` in JavaScript:
```javascript
// JavaScript
g.V().out('created').toObservable()
.subscribe(
function (vertex) {
// This gets called once for each vertex
},
function (err) {
// Handle errors
},
function () {
// Called when observable ends (ie. after last vertex is emitted)
}
)
```
I took a different path in Node.js and started developing
[zer](https://github.com/jbmusso/zer) (short for seriali**zer**), a generic
"JavaScript-to-anything" library that uses the ES2015 Proxy object. The lib
builds an AST-ish (I'm learning these :P) which can output to anything,
including Gremlin-Groovy (currently) and most likely Gremlin-bytcode easily (it
could also output to SQL or Cypher, but hey). The trick is to `Proxy()`ify a
`Function` (rather than an `Object`) and intercept calls to that function with
`Proxy.apply()` and mutation of that function properties with `Proxy.get()`
(you can do both since functions are objects in JavaScript).
The `zer` lib allows generating queries such as
`g.V().out().in().bla().method().not().in().tinkerpop().source().code()`
(Grooovy output) but it could easily support things like
`select().from().where()` (and produce SQL-output). Coding the gremlin-bytecode
output should be trivial. It also supports nested traversals and automatic
escaping of bound parameters (it basically escapes all primitives and anything
that is not a `Traversal`). I think it could also support serializing
functions/lambdas since you can do `Function.toString()` in JavaScript and
extract the function body at runtime.
I donât think that the Proxy approach can work in Nashorn since Proxy
canât be emulated in ES5 environment (it only works in Node v6 I recall,
maybe Node v5). However, in Node.js, I think I would just use Proxy objects
that can intercept anything - I think generating code might not be worth it
there. I think this PR is valid in Nashorn but I'm unsure about Node.js.
Note that `zer` and `gremlin-javascript` are distinct libraries. Once
stable enough, `zer` (with just Gremlin-Groovy and Gremlin-Bytecode output)
could be added as a dependency to `gremlin-javascript`.
---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---