Как решить пирамиду гибели с async / await? - PullRequest
0 голосов
/ 14 сентября 2018

Я хочу знать, как избежать пирамиды гибели этого кода:

Оригинальный код

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

Это нормально? или как я могу использовать этот async / await правильно? Я пытаюсь, что "getPlayerTeamId" и "getPlayers" не должны ожидать параметр обратного вызова и избегать обратного вызова в любом случае.

любой совет? Спасибо и хорошего дня: D

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Я предполагаю, что если вы используете async / await, ваша кодовая база находится в ES6.

Таким образом, вы можете просто использовать Fetch API для замены синтаксиса $.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 вы можете вообще пропустить параметр callback.

Кроме того, вы также можете просто использовать простой Синтаксис Promise :

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 */
          });
    }
};
0 голосов
/ 14 сентября 2018

Пирамида гибели не решается из-за размещения 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"
        });
    }
};

Теперь, когда обещание выполнено , мы можем начать использовать синтаксис обещания .then() или await вместо вложенных обратных вызовов при вызове этих методов:

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