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

Javascript 如何使用async/await解决厄运金字塔?,javascript,ecmascript-6,es6-promise,Javascript,Ecmascript 6,Es6 Promise,我想知道如何避免这个密码的金字塔末日: 原始代码 var PlayerService = { getPlayerTeamId: function(playerId, callback) { $.ajax({ url: "/player/" + playerId + "/team", success: function(team) { callback(team.id)

我想知道如何避免这个密码的金字塔末日:

原始代码

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
            });
        });
    }
};
这是我使用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
            });
        });
    }
};
可以吗?或者如何正确使用此异步/等待?我试图让“getPlayerTeamId”和“GetPlayerPlayer”不应期望回调参数,并以任何方式避免回调


有什么建议吗?谢谢,祝你有一个愉快的一天:D

厄运金字塔不是通过在某处放置
async
/
wait
来解决的,而是通过返回和链接承诺而不是接受回调来解决的。请注意,您的服务方法甚至不需要是
async
,只要它们可以返回一个承诺即可-在任何情况下:

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

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

我假设如果您使用的是async/await,那么您的代码库在ES6中

因此,您实际上可以使用替换
$.ajax({…})
语法:

var PlayerService = {
    getPlayerTeamId: function(playerId) {
        return fetch(`/player/${playerId}/team`);
    },
    getPlayers: function(teamId) {
        return fetch(`/team/${teamId}/player`);
    }
};

var PlayerDetailsController = {
    playerId: 8,
    showTeammatesClick: async function() {
        const teamId = await PlayerService.getPlayerTeamId(this.playerId);
        const playerList = await PlayerService.getPlayers(teamId);

        /* Render playerList here */
    }
};
使用async/await或Promises的目的是避免回调,这解决了“末日金字塔”

因此,在构建
PlayerService
函数时,可以完全跳过
回调
参数

或者,您也可以仅使用普通:


网站上有一些关于这方面的问题,包括和。这两个问题都回答了你的问题吗?
var PlayerService = {
    getPlayerTeamId: function(playerId) {
        return fetch(`/player/${playerId}/team`);
    },
    getPlayers: function(teamId) {
        return fetch(`/team/${teamId}/player`);
    }
};

var PlayerDetailsController = {
    playerId: 8,
    showTeammatesClick: async function() {
        const teamId = await PlayerService.getPlayerTeamId(this.playerId);
        const playerList = await PlayerService.getPlayers(teamId);

        /* Render playerList here */
    }
};
var PlayerService = {
    getPlayerTeamId: function(playerId) {
        return fetch(`/player/${playerId}/team`);
    },
    getPlayers: function(teamId) {
        return fetch(`/team/${teamId}/player`);
    }
};

var PlayerDetailsController = {
    playerId: 8,
    showTeammatesClick: function() {
        PlayerService.getPlayerTeamId(this.playerId)
          .then(PlayerService.getPlayers)
          .then(playerList => {
              /* Render playerList here */
          });
    }
};