2015-08-16 5 views
5

Я работаю над проектом на основе обещаний в Node.js, используя bluebird, а другой - в национальных обещаниях ES6. В обоих случаях, у меня есть цепь, где я запросить базу данных в следующем виде:Функция применяется с Promises

some_function(/*...*/) 

    .then(function() { 
     return query("SELECT `whatever` FROM `wherever` ") 
    }) 

    .then(/*...*/) 

Обратите внимание, что query явно возвращает обещание разрешенное к результату запроса. Это повторяется в нескольких цепочках, и я ищу способ очистить неиспользуемую оболочку функции.

я естественно использовать Function.prototype.apply(), но в этом случае, когда я пытаюсь:

.then(query.apply(this, ["SELECT * FROM ... "])) 
.then(function(rows){ /*...*/ }) 

Следующая функция в цепочке получает rows как undefined.

Спасибо заранее. Ваша помощь приветствуется.

+0

Вы, наверное, хотите [Function.prototype.bind()] (https: // developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) вместо применения: '.then (query.bind (query, SELECT * FROM ...")) '. Вы можете использовать .bind() для создания новой функции на основе 'query' со своей строкой SQL [частично примененной] (https://en.wikipedia.org/wiki/Partial_application). –

+0

'apply' * вызывает * метод (он не возвращает частично примененную функцию), поэтому вы не передаете функцию запроса' then', а возвращаемое значение. – doldt

+0

Подождите, это 'return query.apply (" SELECT ... ")' или 'return query (" SELECT ... ")'? В первом случае у вас есть метод '.apply', который не является * функцией' Function.prototype'. Не смешивайте их. – Bergi

ответ

4

Вы должны передать функции ссылку на .then() так ваш выбор следующим образом:

  1. Использование инлайн анонимной функции, как вы.
  2. Создайте свою собственную функцию полезности, которая возвращает другую функцию (см. Пример ниже).
  3. Используйте .bind() для создания другой функции.

Рядный анонимным

some_function(/*...*/).then(function() { 
    return query.apply("SELECT `whatever` FROM `wherever` ") 
}).then(/*...*/) 

Ваша собственная функция упаковщик

function queryWrap(q) { 
    return function() { 
     return query.apply(q); 
    } 
} 

some_function(/*...*/) 
    .then(queryWrap("SELECT `whatever` FROM `wherever` ")) 
    .then(/*...*/) 

Эта оболочка может быть полезно, если вы могли бы использовать его в нескольких местах. Наверное, это не стоило всего одного вызова.

Использование .bind()

some_function(/*...*/) 
    .then(query.apply.bind(query, "SELECT `whatever` FROM `wherever` ")) 
    .then(/*...*/) 
+0

В последнем примере с 'bind()', почему вы использовали 'query.apply.bind (/*...*/)'? Разве это не 'query.bind (/*...*/)'? Спасибо за ответ. :) – Selfish

3

В ES6, стрелка функции решить эту проблему лучше всего:

.then(() => query.apply("SELECT `whatever` FROM `wherever` ")) 
.then(rows => { /*...*/ }) 
+0

Эй, приятное решение, но решает только один из упомянутых случаев. Спасибо! – Selfish

Смежные вопросы