5

1 回のブックシェルフ トランザクションで多数のデータベース テーブルを更新したいと考えています。コードをリファクタリングするのに役立つことがあります。私はノードを初めて使用し、プロミスについてよく理解していませんが、以下のネストされた構造はあまりきれいではありません。よりクリーンな方法があることを願っています。どんな助けでも大歓迎です。

function insertUser(user, cb) {
  bookshelf.transaction(function(t) {
  var key = user.key;
  Developer.forge({key: key})
  .fetch({require: true, transacting: t})
  .then(function(developerModel) {
    var devID = developerModel.get('id');
    Address.forge(user.address)
    .save(null, {transacting: t})
    .then(function(addressModel) {
      var addressID = addressModel.get('addressId');
      Financial.forge(user.financial)
      .save(null, {transacting: t})
      .then(function(financialModel) {
        var financialID = financialModel.get('financialId');
        var userEntity = user.personal;
        userEntity.addressId = addressID;
        userEntity.developerId = devID;
        userEntity.financialId = financialId;
        User.forge(userEntity)
        .save(null, {transacting: t})
        .then(function(userModel) {
          logger.info('saved user: ', userModel);
          logger.info('commiting transaction');
          t.commit(userModel);
        })
        .catch(function(err) {
          logger.error('Error saving user: ', err);
          t.rollback(err);
        });
      })
      .catch(function(err) {
        logger.error('Error saving financial data: ', err);
        t.rollback(err);
      })
    })
    .catch(function(err) {
      logger.error('Error saving address: ', err);
      t.rollback(err);
    })
  })
  .catch(function(err) {
    logger.error('Error saving business : ', err);
    t.rollback(err);
  })
})
.then(function(model) {
  logger.info(model, ' successfully saved');
  return Promise.resolve(respond.success({userId: model.get('userId')}));
})
.catch(function(err) {
  logger.error(err, ' occurred');
  return Promise.reject(new DatabaseError('Unable to write user to database due to error ', err.message));
})};
4

1 に答える 1

4

結果の約束を変数に保存すると、後で最終的にそれらを使用できます。その後、それらが満たされることが保証され、その値を.value()同期的に取得できます

function insertUser(user, cb) {
  return bookshelf.transaction(function(t) {
    var key = user.key;

    var devID = Developer.forge({key: key})
      .fetch({require: true, transacting: t})
      .call("get", "id");

    var addressID = devID.then(function() {
      return Address.forge(user.address).fetch({require: true, transacting: t})
    }).call("get", "addressId");

    var financialID = addressModel.then(function() {
      return Financial.forge(user.financial).save(null, {transacting: t})
    }).call("get", "financialId");

    var userModel = financialID.then(function() {
      var userEntity = user.personal;
      userEntity.addressId = addressID.value();
      userEntity.developerId = devID.value();
      userEntity.financialId = financialID.value();
      return User.forge(userEntity).save(null, {transacting: t});
    });

    return userModel.then(function(userModel) {
      logger.info('saved user: ', userModel);
      logger.info('commiting transaction');
      t.commit(userModel);
    }).catch(function(e) {
      t.rollback(e);
      throw e;
    });
  });
}
.then(function(model) {
  logger.info(model, ' successfully saved');
  return Promise.resolve(respond.success({userId: model.get('userId')}));
})
.catch(function(err) {
  logger.error(err, ' occurred');
  return Promise.reject(new DatabaseError('Unable to write user to database due to error ', err.message));
})};

別の方法は、次を使用することPromise.joinです。

function insertUser(user, cb) {
  return bookshelf.transaction(function(t) {
    var key = user.key;

    var devID = Developer.forge({key: key})
      .fetch({require: true, transacting: t})
      .call("get", "id");

    var addressID = devID.then(function() {
      return Address.forge(user.address).fetch({require: true, transacting: t})
    }).call("get", "addressId");

    var financialID = addressModel.then(function() {
      return Financial.forge(user.financial).save(null, {transacting: t})
    }).call("get", "financialId");

    var userModel = Promise.join(devID, addressID, financialID,
     function(devID, addressID, financialID) {
      var userEntity = user.personal;
      userEntity.addressId = addressID;
      userEntity.developerId = devID;
      userEntity.financialId = financialID;
      return User.forge(userEntity).save(null, {transacting: t});
    });

    return userModel.then(function(userModel) {
      logger.info('saved user: ', userModel);
      logger.info('commiting transaction');
      t.commit(userModel);
    }).catch(function(e) {
      t.rollback(e);
      throw e;
    });
  });
}
.then(function(model) {
  logger.info(model, ' successfully saved');
  return Promise.resolve(respond.success({userId: model.get('userId')}));
})
.catch(function(err) {
  logger.error(err, ' occurred');
  return Promise.reject(new DatabaseError('Unable to write user to database due to error ', err.message));
})};
于 2015-01-27T17:54:57.170 に答える