书架长的交易问题

时间:2016-11-21 03:40:56

标签: javascript promise bookshelf.js

  function saveReport(t) {
    return new Promise((resolve, reject) => {
      return new Models
        .Cycle()
        .fetchAll()
        .then((cycles) => {
          const promises = cycles.map(cycle => {
            return ReportService
              .getReportByOrgId(cycle.get('orgId'), cycle.id, undefined, t)
              .then(content => {
                let md5 = crypto.createHash('md5');
                let dayNo = parseInt(Date.now() / (1000 * 60 * 60 * 24), 10);
                var id = md5.update(cycle.id + cycle.get('orgId') + 'requestRealTimeReport' + dayNo).digest('hex');
                return new Models
                  .Report()
                  .save({
                    id: id,
                    statistics: JSON.stringify(content)
                  }, {
                    transacting: t,
                    insert: true
                  })
                  .tap(report => {
                    resolve(report);
                  })
                  .catch(console.error);
              })
              .catch(console.error);
          });
          return Promise.all(promises)
        });
    })
  }

  DbService
    .Bookshelf
    .transaction(saveReport)
    .catch(console.error);

当我删除这部分代码时:

.tap(report => {
    resolve(report);
})

它总是伴随着一个很长的事务,我只是想知道在这个.tap()中发生了什么事情它如何阻止来自长事务的事务。

1 个答案:

答案 0 :(得分:0)

代码的tap部分正在解析您在事务回调顶部声明的bluebird Promise

正如documentation所解释的那样,您必须在此处理程序中返回Promise,以便Bookshelf / Knex知道您何时完成了交易中应该包含的所有内容。请注意,当您resolve Promise时,您实际上是在说明您的承诺中的代码已成功完成执行。因此,您要删除的代码块是一个重要的代码块:在某种意义上,它是事务处理程序将控制权传递回Bookshelf的方式。删除它会使Bookshelf处于等待永远不会发生的事情的状态。

我还应注意,您的reject个阻止版中没有catch次呼叫。这样做的结果会导致有问题的行为,因为如果您指定的事务中存在错误,Bookshelf将再次永远不会将控制权传递给它。

阅读蓝鸟网站上的new Promise documentation(甚至是MDN文档)可能会帮助您更好地了解他们的解释,如果我的解释没有帮助。< / p>