Return 毕竟 "on" 事件在 JS promise 中被调用

Return after all "on" events are called inside a JS promise

在 Node.js 中,使用 NodeGit。我在 POST Express.js 路由中使用类似于 this 的函数。这条路线应该得到 endCommitstartCommit:

之间的提交
router.post('/getLog', function(req, res, next) {
    var logData = [];

    Git.Repository.open(path.join(repositories.mine.path))
        .then(function(repo) {
            return {
                    endCommit: [ First commit object ], //Just a random commit object that has a "sha" inside
                    startCommit: [ Second commit object ]  //Just a random commit object that has a "sha" inside
                };
        })
        .then(function(range) {
            // History returns an event.

            var history = range.endCommit.history(Git.Revwalk.SORT.Time);

            // History emits "commit" event for each commit in the branch's history
            history.on("commit", function(commit) {
                logData.push({
                    commit: commit.sha(),
                    message: commit.message()
                });

                if (commit.sha() == range.startCommit.sha()) {
                    console.log("---LOG CREATED---");
                    history.end();
                }
            })

            history.start();
        })
        .done(function() {
            console.log("---RETURNING---");

            return res.json({ logData: logData });
        });
});

但是,由于 history.on("commit", ...) 不是 Promise,因此首先调用 .done() 函数。在日志中我看到:

---RETURNING---
---LOG CREATED---

如何才能return创建日志后才能

我过去遇到过类似的问题,但在这种特殊情况下,我不知道如何 promisify 历史对象,因为它基于事件。

您可以将事件处理包装在完成后应解决的承诺中,return它:

.then(function(range) {
  // History returns an event.

  var history = range.endCommit.history(Git.Revwalk.SORT.Time);

  var commitPromise = new Promise(function(resolve, reject) {
    // History emits "commit" event for each commit in the branch's history
    history.on("commit", function(commit) {
      logData.push({
        commit: commit.sha(),
        message: commit.message()
      });

      if (commit.sha() == range.startCommit.sha()) {
        console.log("---LOG CREATED---");
        resolve(); // resolve the promise
        history.end();
      }
    })
  });

  history.start();

  return commitPromise;
})

我假设你有 Promise 全局。这取决于您选择特定的承诺实现 - 例如,您可能想使用 bluebird