如何使用Node.js承诺函数(执行查询时的CassandraDB驱动程序)

时间:2018-05-26 20:12:08

标签: node.js asynchronous cassandra promise datastax-enterprise

我正在使用来自Cassandra DB驱动程序的client.stream()来获取使用页面的大型结果集,然后对于返回的每一行结果,我将其推送到我的范围顶部定义的数组中。

查询完成后,我想返回我的数组,但它总是返回' undefined'我猜它是因为获取查询需要很长时间,所以Javascript在对象被填充之前继续使用return语句。

对于那些不熟悉这个驱动程序的人:client.stream是一个函数,获取一些数据需要一些时间。在返回对象之前,我需要等待这个完成!

E.g

function foo() {
  var resultArray: [];
  var query = "select username from users where userRank = 3";
  client.stream(query, {prepare: true})
    .on('readable' function () {
      var row;
      while (row = this.read()) {
        resultArray.push(row.username); 
      }
    })
    .on('end', function () {
      return obj; // The object only exists in this scope but cant return from here
    });
}

当我调用此var returned = foo();时,我会将undefined作为返回值。

2 个答案:

答案 0 :(得分:1)

如果您想使用stream API,则需要创建自己的Promise实例,并在流结束时解析它。

没有必要自行缓冲所有行,然后返回Promise,驱动程序可以为您执行此操作。如果你不关心在内存中拥有所有这些行的内存消耗,你可以这样做:

// Disable paging
// NOTE: Memory consumption will depend on the amount of rows
// and the amount of concurrent requests
const options = { prepare: true, fetchSize: 0 };
const promise = client.execute(query, params, options);

有关详细信息,请参阅文档:https://docs.datastax.com/en/developer/nodejs-driver/latest/features/paging/

答案 1 :(得分:0)

要添加到答案中,我能够将stream包装在Promise中。

            new Promise((resolve, reject) => {
                const results = [];

                return client
                    .stream(query, params, options)
                    .on('readable', function() {
                        // 'readable' is emitted as soon a row is received and parsed
                        let row;

                        while ((row = this.read())) {
                            results.push(row);
                        }
                    })
                    .on('end', function() {
                        // Stream ended, there aren't any more rows
                        return resolve(results);
                    })
                    .on('error', function(err) {
                        return reject(err);
                    });
            }),