2017-02-06 3 views
0

В Node.js, используя NodeGit. Я использую функцию, похожую на this внутри маршрута POST Express.js. Этот маршрут должен получить совершающие между endCommit и startCommit:Возврат после всех событий «on» вызывается внутри обещания JS

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--- 

Как я могу вернуться только после того, как журнал был создан?

Я наткнулся на вопросы, как это в прошлом, однако в данном случае я не знаю, как я мог promisify объекта истории, поскольку она основана на событиях.

ответ

1

Вы можете обернуть обработку в обещании, которое должно быть разрешено, как только вы сделали событие, и вернуть его:

.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.

+0

Большое спасибо! Ты указал мне на правильный путь. Теперь он работает, но требуется только небольшое изменение: 'resolve()' должен появиться перед 'history.end()' иначе строка никогда не будет выполнена. Я уже изменил ответ для вашего удобства. – adelriosantiago

+1

@adelriosantiago единственная причина, по которой я вижу, что 'разрешение' не будет выполняться, если помещено после' history.end() ', является последним, выкидывающим ошибку. Посмотрите на это, чтобы предотвратить возможные проблемы. –

+0

Вы правы, 'history.end()' не существует. Я решил, что заменив его «throw Git.Error.CODE.ITEROVER», как здесь: https://github.com/nodegit/nodegit/blob/a7bde084cdc3537dd30522bb8fa1e6f2ff724898/lib/revwalk.js#L81. – adelriosantiago