如何用 async/await 解决厄运金字塔?

Dei*_*bid 2 javascript ecmascript-6 es6-promise

我想知道如何避免这段代码的厄运金字塔:

原码

var PlayerService = {
    getPlayerTeamId: function(playerId, callback) {
        $.ajax({
            url: "/player/" + playerId + "/team",
            success: function(team) {
                callback(team.id)
            }
        });
    },
    getPlayers: function(teamId, callback) {
        $.ajax({
            url: "/team/" + teamId + "/player",
            success: callback
        });
    }
};

var PlayerDetailsController = {
    playerId: 8,
    showTeammatesClick: function() {
        PlayerService.getPlayerTeamId(this.playerId, function(teamId) {
            PlayerService.getPlayers(teamId, function(playerList) {
                // Render playerList
            });
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

这是我的 async/await 版本,以避免出现金字塔: 我的版本

var PlayerService = {
    getPlayerTeamId: async function(playerId, callback) {
        return await $.ajax({
                   url: "/player/" + playerId + "/team",
                   success: function(team) {
                       callback(team.id)
                   }
               });
    },
    getPlayers: async function(teamId, callback) {
        return await $.ajax({
                   url: "/team/" + teamId + "/player",
                   success: callback
               });
    }
};

var PlayerDetailsController = {
    playerId: 8,
    showTeammatesClick: function() {
        PlayerService.getPlayerTeamId(this.playerId, function(teamId) {
            PlayerService.getPlayers(teamId, function(playerList) {
                // Render playerList
            });
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

可以吗?或者我如何正确使用这个异步/等待?我正在尝试“getPlayerTeamId”和“getPlayers”不应该期待回调参数,并以任何方式避免回调。

有什么建议吗?谢谢,祝你有美好的一天:D

Ber*_*rgi 5

末日金字塔不是通过放置async/解决的await,而是通过返回和链接承诺而不是接受回调来解决的。请注意,您的服务方法甚至不需要async在它们可以返回承诺时使用 - 在任何情况下都不要使用return await

const PlayerService = {
    getPlayerTeamId(playerId ) {
//                          ^ no callback
        return $.ajax({
//      ^^^^^^ the promise
            url: "/player/" + playerId + "/team"
        }).then(team => team.id);
    },
    // same here
    getPlayers(teamId) {
        return $.ajax({
            url: "/team/" + teamId + "/player"
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

现在promisification已经完成,我们可以开始使用promise.then()awaitsyntax 而不是在调用这些方法时嵌套回调:

const PlayerDetailsController = {
    playerId: 8,
    async showTeammatesClick() {
        const teamId = await PlayerService.getPlayerTeamId(this.playerId);
        const playerList = await PlayerService.getPlayers(teamId);
        … // Render playerList
    }
};
Run Code Online (Sandbox Code Playgroud)