如何从承诺中的事件处理程序返回值?

我正在构build一个使用nodegit npm包的nodeJS应用程序。 所以根据他们的文档中的例子,我有以下章节。 它使用了一系列的promise,看起来像一个JQuery事件处理程序。 这是我的function:

 export function prepareDiffs() { var patt = new RegExp('[0-9].[0-9]'); var results: Array<Commit> = []; Git.Repository.open("features/tutorial") // Open the repository directory. .then(function (repo) { // Open the master branch. return repo.getMasterCommit(); }) .then(function (firstCommitOnMaster) { // Display information about commits on master. var history = firstCommitOnMaster.history(); // Create a new history event emitter. history.on("commit", function (commit) { // Listen for commit events from the history. var entry = new Commit(); entry.hash = commit.sha(); var step = patt.exec(commit.message()); if (step !== null) { entry.step = step.toString(); } results.push(entry); }) history.start(); // Start emitting events. console.log("return"); }); } 

所以把console.log放在history.on()事件处理程序中显示了所有我想查看的信息。 所以我相当有信心在我的数组推动。 那么我怎样才能得到prepareDiffs()函数来返回填充的results数组,或者至less是parsing到数组的promise?

注意:我使用的是针对es6的Typescript,所以async / await是可用的。

让你的第二次callback创build并返回一个承诺,然后监听end事件,并解决在这一点上的承诺与您的数组,请参阅***评论:

 export function prepareDiffs() { var patt = new RegExp('[0-9].[0-9]'); var results: Array<Commit> = []; // *** Note we're returning the result of the promise chain return Git.Repository.open("features/tutorial") // Open the repository directory. .then(function (repo) { // Open the master branch. return repo.getMasterCommit(); }) .then(function (firstCommitOnMaster) { // Display information about commits on master. // *** Create and return a promise return new Promise(function(resolve, reject) { var history = firstCommitOnMaster.history(); // Create a new history event emitter. history .on("commit", function (commit) { // Listen for commit events from the history. var entry = new Commit(); entry.hash = commit.sha(); var step = patt.exec(commit.message()); if (step !== null) { entry.step = step.toString(); } results.push(entry); }) .on("end", function() { // *** Listen for the end // *** Resolve the promise resolve(results); }); history.start(); // Start emitting events. console.log("return"); }); }); } 

我想强调一下, 大多数情况下,当您已经处理基于承诺的API 时,您不希望创build新的承诺 。 但是在这种情况下,因为你从event发送器的history()返回中得到一系列的asynchronouscommit事件,所以你不能直接使用promise链,所以在这里创build一个promise是可以的。

请注意, 我们创build它。 我们在那里做,所以如果由Git.Repository.opengetMasterCommit返回的诺言拒绝,调用者看到拒绝。

这是一个使用asynchronous/等待的版本。 您可以使用await来调用返回Promise的任何函数。 注意prepareDiffs返回包装事件发射器的Promise。

  export function prepareDiffs(): Promise<Commit[]> { return new Promise<Commit[]>(async (resolve, reject) => { var repo = await Git.Repository.open("features/tutorial"); var masterCommit = await repo.getMasterCommit(); var history = masterCommit.history(); var result: Commit[] = []; history.on("commmit", commit => { var entry = new Commit(); entry.hash = commit.sha(); var step = /[0-9].[0-9]/.exec(commit.message()); if (step !== null) entry.step = step.toString(); result.push(entry); }); history.on("end", () => resolve(result)); history.on("error", err => reject(err)); history.start(); }); } 

像这样称呼…

 var commits = await prepareDiffs();