Как использовать Model.query() с промисами в SailsJS/Waterline?

У меня проблемы с Sails.JS 0.9.8. Я хотел бы использовать промисы с функцией Model.query() (я использую адаптер паруса-mysql).

Этот код будет работать:

User.findOne({ email: email })
.then(function(user) {
  console.log(user);
});

но этот не будет

User.query("SELECT email FROM user WHERE email = ?", [ email ]))
.then(function(err, rows) {
  console.log(rows);
})

Я получаю undefined как для «ошибки», так и для «строк».

Это просто не реализовано или я что-то не так делаю? Если не реализовано, есть ли альтернатива использованию обещаний с .query()?

заранее спасибо


person YannP    schedule 19.02.2014    source источник


Ответы (4)


Вы можете promisify(User.query) самостоятельно, как и для любого другого API на основе обратного вызова, например:

var Promise = require('bluebird');

....

var userQueryAsync = Promise.promisify(User.query);
userQueryAsync("SELECT email FROM user WHERE email = ?", [ email ])
.then(function(user) {
    console.log(user);
});
person Steve Kehlet    schedule 06.11.2014
comment
Очень приятно - теперь мы даем ссылку со справочной страницы .query() в документации по парусам. - person mikermcneil; 26.01.2016
comment
Я получаю только node_modules/sails-mysql/node_modules/mysql/lib/protocol/Parser.js:77 throw err; // Повторно сгенерировать ошибки, отличные от MySQL ^ RangeError: Offset is out of bounds - person Crusader; 31.10.2016

В качестве хака вы можете пропатчить все свои модели в бутстрапе вот так

module.exports.bootstrap = function(cb) {
    var Promise = require('bluebird');

    Object.keys(sails.models).forEach(function (key) {
        if (sails.models[key].query) {
            sails.models[key].query = Promise.promisify(sails.models[key].query);
        }
    });

    cb();
};
person Chad Scira    schedule 07.12.2015

Метод query специфичен для парусов-mysql и не поддерживает отложенные объекты так, как это делают более общие методы адаптера Waterline (например, findOne, find, create и т. д.). Вам нужно будет указать обратный вызов в качестве второго аргумента.

person sgress454    schedule 19.02.2014

Если вы не хотите использовать обещание, но хотите, чтобы SailsModel.query возвращал обещание.

/**
 * @param {Model} model - an instance of a sails model
 * @param {string} sql - a sql string
 * @param {*[]} values - used to interpolate the string's ?
 *
 * @returns {Promise} which resolves to the succesfully queried strings
 */
function query(model, sql, values) {
  values = values || [];

  return new Promise((resolve, reject) => {

    model.query(sql, values, (err, results) => {
      if (err) {
        return reject(err);
      }

      resolve(results);
    });
  });
}

// and use it like this
query(User, 'SELECT * FROM user WHERE id = ?', [1]).then(console.log);
person bas080    schedule 07.10.2016