【问题标题】:How to return values from an event handler in a promise?如何从承诺中的事件处理程序返回值?
【发布时间】:2016-08-14 12:40:15
【问题描述】:

我正在构建一个使用 nodegit npm 包的 nodeJS 应用程序。因此,根据他们文档中的示例,我有以下章节。它使用一系列承诺,看起来像一个 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");
        });
}

因此,将 console.log 放入 history.on() 事件处理程序会显示我想要查看的所有信息。所以我对我的阵列推动相当有信心。那么如何让prepareDiffs() 函数返回填充的results 数组或至少一个解析为数组的承诺?

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

【问题讨论】:

    标签: javascript jquery node.js typescript


    【解决方案1】:

    让您的第二个then 回调创建并返回一个promise,然后侦听end 事件并在此时使用您的数组解决promise,参见*** cmets:

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

    我想强调的是,大多数时候,当您已经在处理基于 Promise 的 API 时,您不想创建新的 Promise。但是在这种情况下,因为你从事件发射器history()返回中得到了一系列异步commit事件,所以你不能直接使用promise链,所以在这里创建一个promise是可以的。

    注意何时我们创建它。我们在那里这样做是为了如果 Git.Repository.open 或 getMasterCommit 返回的承诺被拒绝,调用者会看到该拒绝。

    【讨论】:

      【解决方案2】:

      这是一个使用 async/await 的版本。 您可以使用 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();
      

      【讨论】:

        猜你喜欢
        • 2017-12-26
        • 2019-01-24
        • 1970-01-01
        • 2020-08-17
        • 1970-01-01
        • 1970-01-01
        • 2021-01-24
        • 2021-07-22
        • 2018-07-22
        相关资源
        最近更新 更多