Javascript 将for循环转换为Q承诺

Javascript 将for循环转换为Q承诺,javascript,arrays,q,Javascript,Arrays,Q,我是一个新的承诺者,并且尝试在for循环中使用承诺 function query(queryString, keywords) { var defer = q.defer(); connection.query(queryString + '"' + keywords + '"', function (err, rows) { if (err) { defer.reject(err); } else { defer.resolve(rows[0])

我是一个新的承诺者,并且尝试在for循环中使用承诺

function query(queryString, keywords) {
  var defer = q.defer();
  connection.query(queryString + '"' + keywords + '"', function (err, rows) {
    if (err) {
      defer.reject(err);
    } else {
      defer.resolve(rows[0]);
    }
  });
  return defer.promise;
}

q.all([
  query(testQuery, 'test1'),
  query(testQuery, 'test2')
]).then(console.log, console.log);
上面的代码正在运行并返回一个结果数组

我试图做的是使用for循环,这样我就不需要每次都编写查询了

query(testQuery, 'test1'),
query(testQuery, 'test2'),
query(testQuery, 'test3'),
query(testQuery, 'test4')
这是我的最新代码:

function query(queryString, keywords) {
  var defer = q.defer(),
      results = [];
  for (var i = 0; i < keywords.length; i++) {
    connection.query(queryString + '"' + keywords[i] + '"', function (err, rows) {
      if (err) {
        defer.reject(err);
      } else {
        results.push(rows[0]);;
      }
    });
  }
  defer.resolve(results);
  return defer.promise;
}

var tests = ['test1', 'test2'];

q.all(query(testQuery, tests)).then(console.log, console.log);
上面的代码不起作用,返回一个空数组

这似乎不是使用for循环表示承诺的正确方法。那么在这种情况下,如何在for循环之后返回承诺数组呢

谢谢

基于@Bergi评论的更新版本:

function query(queryString, keywords) {
  var defer = q.defer();
  connection.query(queryString + '"' + keywords + '"', function (err, rows) {
    if (err) {
      defer.reject(err);
    } else {
      defer.resolve(rows[0]);
    }
  });
  return defer.promise;
}

var tests = ['test1', 'test2'],
    results = [];

for (var i = 0; i < tests.length; i++) {
  results.push(query(testQuery, tests[i]));
}

q.all(results).then(console.log, console.log);

这是可行的,但我想知道是否有办法在查询函数中包含for循环。因为每次使用此方法时,我都必须编写for循环。

它应该是这样的:

function query(queryString, keywords) {
    var promiseArr = [];

    for (var i = 0; i < keywords.length; i++) {
        var deferred = $q.defer();
        promiseArr.push(deferred.promise);

        connection.query(queryString + '"' + keywords[i] + '"', function (def) {
            return function (err, rows) {
                if (err) {
                    def.reject(err);
                } else {
                    def.resolve(rows[0]); // what is rows and why just rows[0]???
                }
            };
        }(deferred));
    }

    return promiseArr;
}

var tests = ['test1', 'test2'];
q.all(query(testQuery, tests)).then(console.log, console.log);

下面是一个使用下划线库获得所需结果的版本。你将不得不使用一些增加范围级别的东西。本机映射和下划线映射都可以工作

function query(queryString, keywords) {
    return _.map(keywords, function(keyword) {
        return Q.promise(resolve, reject) {
            connection.query(queryString + '"' + keyword + '"', function (err, rows) {
                if (err) {
                    reject(err);
                } else {
                    resolve(rows[0]);
                }
            });
        };
    });
}

var tests = ['test1', 'test2'],
    results;


q.all(query(testQuery, tests).then(console.log, console.log);

将循环移到查询函数之外。然后创建一个可以传递给Q的数组。就像在第一个代码片段中一样。如果您希望在该循环中使用函数,请引入第二个函数。尽量不要把所有东西都塞进一个函数中。@amir popvich answer现在也可以工作了。我们基本上有两种相反的方法可以达到相同的结果。