For循环进行异步调用后,Q无法解析

时间:2014-03-05 05:40:35

标签: mysql node.js asynchronous promise q

这里很简单,但似乎我错过了一些细微差别。我正在创建一个promises数组,并使用Q.all()确保在将响应发送回客户端之前完成对db的所有插入。但是,它从未被调用过。如何才能收到要发送的回复?

    var promises = [];

    for(var i=0; i < rows.length; i++){
        // Insert new row here
        var def = Q.defer();
        promises.push(def.promise);

        var query = connection.query(createQuery(rows[i]), function(err, rows) {
          if(err) {
            console.log(err);
            return;
          }
        });

        query.on('end', function(){
            console.log(def);
            def.resolve();
        });


    }

    Q.all(promises).then(function() {
       res.json({success:true, rows: rows.length});
    });

2 个答案:

答案 0 :(得分:1)

您对def.resolve()的来电无法预测。如果您的查询需要时间,则所有查询都将一次又一次地解析最后一次def。你也需要维护一组defs。

var promises = [], defs = [];

现在找出一种方法将各个defs与正确的查询连接起来,并在解析查询时解析def。

或者您可以在匿名函数中调用查询函数。在这种情况下,您不需要defs数组。

function(def) {
    var query = connection.query(createQuery(rows[i]), function(err, rows) {
        if(err) {
            console.log(err);
            return;
        }
    });

    query.on('end', function(){
        console.log(def);
        def.resolve();
    });
}(def);

OR 把那部分拿出去,然后把它变成一个函数。

function queryRow(row, def) {
    var query = connection.query(createQuery(row), function(err, rows) {
        if(err) {
            console.log(err);
            return;
        }
    }); 

    query.on('end', function(){
        console.log(def);
        def.resolve();
    });
}

queryRow(rows[i], def);

或者,您可以使用q的denodeify or nfbind函数并将您的mysql查询函数转换为返回promise的函数。

答案 1 :(得分:0)

使用.map().nfbind

var queryAsync = Q.nfbind(connection.query, connection);
Q.all(rows.map(function(row)) {
    return queryAsync(createQuery(row));
})).then(function() {
    res.json({success:true, rows: rows.length});
});