每个asynchronous任务在forEach中完成后执行一次callback

我正在编写一些PostgreSQL事务,并且一旦forEach中的每个函数都执行完毕,我需要执行callback。 这里是一些代码:

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 }); }); }); 

我看了asynchronous,但我不知道如何,或者如果我可以,适用于我的情况。

有什么想法?

谢谢!

结合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 }); 

它可能需要一些调整,取决于你想要的结果。

如果你不想使用asynchronous(它有时使简单的应用程序复杂),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 }); }); });