diff --git a/lib/cursor.js b/lib/cursor.js index 3cd9c77..9db9885 100644 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -2,6 +2,7 @@ var Promise = require('bluebird'); var Err = require(__dirname+'/error.js'); var helper = require(__dirname+'/helper.js'); var EventEmitter = require('events').EventEmitter; +var $$asyncIterator = require('iterall').$$asyncIterator; var MAX_CALL_STACK = 1000; @@ -366,6 +367,37 @@ Cursor.prototype._eachCb = function(err, data) { } } +Cursor.prototype.asyncIterator = function() { + var self = this; + return { + next: function() { + var iter = this; + return self._next().then(value => { + return { + done: false, + value: value + }; + }).error(function(error) { + if ((error.message !== 'You cannot retrieve data from a cursor that is closed.') && + (error.message.match(/You cannot call `next` on a closed/) === null)) { + return iter.throw(error); + } else { + return iter.return(); + } + }); + }, + return: function() { + return Promise.resolve({ value: undefined, done: true }); + }, + throw: function(err) { + return Promise.reject(err); + }, + [$$asyncIterator]: function() { + return this; + } + +}} + var methods = [ 'addListener', 'on', diff --git a/package.json b/package.json index e73e4e7..f05b6a5 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "url": "https://github.com/neumino/rethinkdbdash/issues" }, "dependencies": { - "bluebird": ">= 3.0.1" + "bluebird": ">= 3.0.1", + "iterall": "^1.2.2" }, "devDependencies": { "mocha": ">= 1.20.0", diff --git a/test/cursor.js b/test/cursor.js index 73e9589..018632f 100644 --- a/test/cursor.js +++ b/test/cursor.js @@ -2,6 +2,7 @@ var config = require('./config.js'); var r = require('../lib')(config); var util = require(__dirname+'/util/common.js'); var assert = require('assert'); +var iterall = require('iterall'); var uuid = util.uuid; var It = util.It @@ -841,5 +842,35 @@ It('`eachAync` should return an error if the connection dies', function* (done) // Kill the TCP connection connection.connection.end() }) +It('`asyncIterator` should return an async iterator', function* (done) { + try { + var connection = yield r.connect({host: config.host, port: config.port, authKey: config.authKey}); + assert(connection); - + var feed = yield r.db(dbName).table(tableName).changes().run(connection); + var iterator = feed.asyncIterator(); + assert(iterall.isAsyncIterable(iterator)) + connection.connection.end() + done(); + } catch(err) { + done(err); + } +}) +It('`asyncIterator` should have a working `next`method', function* (done) { + try { + feed = yield r.db(dbName).table(tableName2).changes().run(); + var value = 1; + setTimeout(function() { + r.db(dbName).table(tableName2).update({foo: value}).run(); + }, 100) + assert(feed); + var iterator = feed.asyncIterator(); + assert(iterator); + var i=0; + var result = yield iterator.next(); + assert(result.value.new_val.foo === value); + done(); + } catch(err) { + done(err); + } +})