在forEach中完成每个异步任务后执行回调

时间:2013-08-19 19:13:04

标签: node.js postgresql asynchronous

我正在编写一些PostgreSQL事务,并且我需要在执行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,但我不确定如何,或者我是否可以将它应用于我的情况。

有任何想法吗?

谢谢!

2 个答案:

答案 0 :(得分: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 :(得分:1)

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