@SkyTaurus

Как использовать defer.resolve и Q.all?

Необходимо написать код, который в зависимости от условия формирует тот или иной sql-запрос, а затем выполняет его.
Пробовал несколько вариантов, но получить желаемый результат не удалось - сочетание dever.resolve и Q.all работает не так, как мне нужно.

В этом варианте node.js выполняет deferrer.resolve раньше, чем Q.all, т.е на момент deferrer.resolve данных еще нет.

deferred = Q.defer()
if условие
   сформировать_sql_запрос
   deferred.resolve
else
   получить_дополнительные_данные
   Q.all(выполнить_sql_запросы_по_дополнительным_данным).then =>
      сформировать_sql_запрос
   deferred.resolve
deferred.promise.then =>
   выполнить_sql_запрос


В этом варианте node.js выполняет deferrer.resolve по завершению выполнения Q,all, но перед выполнением .then у Q.all.

deferred = Q.defer()
if условие
   сформировать_sql_запрос
   deferred.resolve
else
   получить_дополнительные_данные
   deferred.resolve Q.all(выполнить_sql_запросы_по_дополнительным_данным).then =>
      сформировать_sql_запрос
deferred.promise.then =>
   выполнить_sql_запрос
  • Вопрос задан
  • 216 просмотров
Решения вопроса 1
Staltec
@Staltec
Node.js разработчик
Тут можно вообще обойтись без промисов:
var async = require('async');
var mysqlConnection = ...;

function fetch (param, fetchCallback) { // fetchCallback (err, fetchedData)
    async.auto({

        queryOne: function (cb) {
            // если нет параметра для первого запроса идём дальше
            if (!param) return cb(null, null); 

            // сформировать_sql_запрос
            var queryStr = "QUERY TYPE ONE " + mysqlConnection.escape(param);
            cb(null, queryStr);
        },

        queryTwo: ['queryOne', function (cb, results) {
            // если первый запрос сформирован сразу идём дальше
            if (results.queryOne) return cb(null, null); 

            mysqlConnection.query("QUERY TO GET ADDITIONAL DATA", [...], function (err, data) {
                if (err) return cb(err);

                // сформировать_sql_запрос используя дополнительные данные из data
                var additionalParam = data[0]&& data[0].field || 'An default';
                var queryStr = "QUERY TYPE TWO BY ADDITIONAL DATA "  + mysqlConnection.escape(additionalParam);

                cb(null, queryStr);
            });
        }]

    }, function (err, results) {
        if (err) return fetchCallback(err);

        mysqlConnection.query(results.queryOne || results.queryTwo, [...], fetchCallback);
    });
}

Конструируя запросы с использованием внешних параметров не забывайте про вызов для них mysqlConnection.escape(unsafe_param) чтобы избежать SQL-инъекций.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы