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

时间:2016-08-14 12:40:16

标签: javascript jquery node.js typescript

我正在构建一个使用nodegit npm包的nodeJS应用程序。因此,根据他们的文档中的示例,我有以下章节。它使用一系列promises,看起来像一个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数组或至少一个解析为数组的promise?

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

2 个答案:

答案 0 :(得分: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时,大部分时间,您都不想创建新的承诺。但在这种情况下,因为您从事件发送者commit返回一系列异步history()事件,您无法直接使用保证链,因此创建承诺是好的,这里。

注意 时我们创建它。我们在那里执行此操作,以便如果Git.Repository.opengetMasterCommit返回的承诺拒绝,则来电者会看到拒绝。

答案 1 :(得分:0)

这是一个使用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();