2016-08-14 105 views
1

我正在構建一個使用nodegit npm包的nodeJS應用程序。因此,根據他們的文檔中的示例,我有以下章節。它使用一系列的promise,看起來像一個JQuery事件處理程序。這裏是我的功能:如何從承諾中的事件處理程序返回值?

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"); 
     }); 
} 

所以在history.on()事件處理程序將執行console.log顯示了所有的信息,我想看到的。所以我對陣列的推動很有信心。所以我怎樣才能得到prepareDiffs()函數返回填充的results數組或至少一個承諾解決陣列?

注意:我正在使用Typescript定位es6,因此async/await可用。

回答

2

有你的第二個then回調創建並返回一個承諾,然後偵聽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時,您不希望創建新的承諾。但是在這種情況下,因爲您從事件發送器history()返回的一系列異步事件發生,您不能直接使用承諾鏈,因此在此處創建承諾是可以的。

注意當我們創建它。我們在那裏這樣做,以便如果由Git.Repository.opengetMasterCommit拒絕返回的承諾,呼叫者看到拒絕。

0

這是一個使用異步/等待的版本。 您可以使用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();