2013-08-19 3 views
1

Я пишу несколько транзакций PostgreSQL, и мне нужно выполнить обратный вызов после выполнения каждой функции в forEach. Вот код:Выполнять обратный вызов после завершения всех задач async в forEach

var sql = "BEGIN;UPDATE object SET name = "+data.name+", object_subtype_id = "+data.object_subtype_id+" WHERE id = "+data.id+";"; 
db.driver.execQuery(sql, function(err, result) { 
    data.object_subtype.object_property_type.forEach(function(item) { 
    db.driver.execQuery("WITH upsert AS (UPDATE object_property SET value = '"+item.value+"' WHERE object_property_type_id = "+item.id+" AND object_id = "+data.id+" RETURNING *) INSERT INTO object_property (object_property_type_id, object_id, value) SELECT "+item.id+", "+data.id+", '"+item.value+"' WHERE NOT EXISTS (SELECT * FROM upsert);", function(err, nb) { 
     // I need to send the COMMIT; here once all the functions in the forEach have been executed 
    }); 
    }); 
}); 

Я имел взгляд на async, но я не знаю, как, или если я могу, применить его к моей ситуации.

Есть идеи?

Спасибо!

ответ

1

Объединение async.series и async.each вы в конечном итоге с этим красивым сниппета:

var sql = "BEGIN;UPDATE object SET name = "+data.name+", object_subtype_id = "+data.object_subtype_id+" WHERE id = "+data.id+";"; 

async.series([ 
    function (next) { 
    db.driver.execQuery(sql, next); 
    }, 
    function (next) { 
    async.each(data.object_subtype.object_property_type, function (item, next) { 
     db.driver.execQuery("WITH upsert AS (UPDATE object_property SET value = '"+item.value+"' WHERE object_property_type_id = "+item.id+" AND object_id = "+data.id+" RETURNING *) INSERT INTO object_property (object_property_type_id, object_id, value) SELECT "+item.id+", "+data.id+", '"+item.value+"' WHERE NOT EXISTS (SELECT * FROM upsert);", next); 
    }, next); 
    } 
], function (err, results) { 
    // Not sure what you want to do with the result 
}); 

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

1

Если вы не хотите использовать async (иногда это усложняет простые приложения), метод JS заключается в подсчете ссылок. Сделай это;

var sql = "BEGIN;UPDATE object SET name = "+data.name+", object_subtype_id = "+data.object_subtype_id+" WHERE id = "+data.id+";"; 
db.driver.execQuery(sql, function(err, result) { 
    var counter =0; 
    data.object_subtype.object_property_type.forEach(function(item) { 
    db.driver.execQuery("WITH upsert AS (UPDATE object_property SET value = '"+item.value+"' WHERE object_property_type_id = "+item.id+" AND object_id = "+data.id+" RETURNING *) INSERT INTO object_property (object_property_type_id, object_id, value) SELECT "+item.id+", "+data.id+", '"+item.value+"' WHERE NOT EXISTS (SELECT * FROM upsert);", function(err, nb) { 
     //THIS IS WHERE REFERENCE COUNTING HAPPENS 
     counter++; 
     if(counter === data.subtype.type.length) { 
      COMMIT (since all callback functions returned 
     } 
     // I need to send the COMMIT; here once all the functions in the forEach have been executed 
    }); 
    }); 
}); 
Смежные вопросы