用下划线地图做一些异步的事情

Do something async with underscore map

function addSomething(data) {
    var defer = q.defer();
    data = _.map(data, function(item) {
            item['something'] = callSomethingAsync();
            return item;
    });
    return defer.promise;
}

我该如何处理这个问题。我发现的唯一方法是使用 Async.js。 但也许有更好的方法使用 $q?

编辑:

function getScopes(item) {
    var defer = q.defer();
    var query = "SELECT somevalue FROM Something WHERE ID = '" + item.id + "'";
    mysql.query(query, function(err, data) {
        if (err) {
            defer.reject(err);
        } else {
            item[newkey] = data
            defer.resolve(item);
        }
    });
    defer.resolve(data)
    return defer.promise;
}

//add necessary scopes to the audit
function addScopes(data) {
    var promises = _.map(data, function(item) {
        return getScopes(item);
    });
    return Promise.all(promises);
}

如何防止在 getScopes 函数中使用延迟?

编辑 2:

var query = "SELECT * FROM tiscope";
Q.nfcall(mysql.query, query).then(function(data) {
        console.log(data);
});

没有返回任何内容。

我是这样使用的 mysql:

var sql = require('mysql');

var connection = sql.createConnection({
    host     : 'xxx',
    user     : 'xxx',
    password : 'xxx',
    database : 'xxx'
});

connection.connect(function(err) {
    if (err) {
        console.error('error connecting: ' + err.stack);
    } else {
        console.log('mysql connection established');
    }
});

module.exports = connection;

可能有误

很多 promise 库都提供了 map 函数。似乎Q没有。无论如何使用 all 函数都可以用普通的承诺(和 Q)完成同样的事情。

要事第一。避免 defer。它使代码更难推理和维护。需要延迟的情况很少见。其余时间,正常的 promise constructor/helper 函数会更好地工作。

普通 Promise 示例

function addSomething() {
  var promises = _.map(data, function(item) {
    return callSomethingAsync(item);
  });
  return Promise.all(promises);
}

Q 承诺示例

function addSomething() {
  var promises = _.map(data, function(item) {
    return callSomethingAsync(item);
  });
  return $q.all(promises);
}

大概是callSomethingAsyncreturns一个承诺。如果不使用 promise 构造函数模式:

function toPromise(asyncFn, args) {
  return new Promise(function (resolve, reject) {
    function callback(err, result) {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    }
    asyncFn(callback, args);
  });
}

function addSomething() {
  var promises = _.map(data, function(item) {
    return toPromise(callSomethingAsync, item);
  });
  return Promise.all(promises);
}