Как использовать обещания Node.js для функции (драйвер CassandraDB при выполнении запроса) - PullRequest
0 голосов
/ 26 мая 2018

Я использую client.stream () из драйвера Cassandra DB для извлечения больших наборов результатов, используя страницы, затем для каждого возвращаемого результата строки я помещаю его в массив, определенный в верхней части моей области видимости.

После того, как запросы завершены, я хочу вернуть свой массив, но он всегда возвращает 'undefined', и я угадываю его, потому что выборка запросов занимает много времени, поэтому Javascript продолжает выполнение оператора return до того, как объект станет четнымpopulated.

Для тех, кто не знаком с этим драйвером: client.stream - это функция, и для получения некоторых данных требуется некоторое время.Мне нужно подождать, пока это закончится, прежде чем возвращать объект!

Например

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 голосов
/ 14 августа 2019

Чтобы добавить к ответу, я смог заставить stream работать, завернутый в Обещание.

            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);
                    });
            }),
0 голосов
/ 28 мая 2018

Если вы хотите использовать 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/

...