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.
---

Reply via email to