Работа с вложенными асинхронными циклами, попытка получить один выход, когда это будет сделано - PullRequest
0 голосов
/ 11 мая 2018

В основном я пытаюсь извлечь некоторые данные из mongodb, изменить их и отправить в ответ клиенту. Чтобы изменить данные, которые мне нужны, требуется 2 для циклов, во втором цикле вызывается функция, которая редактирует данные и выдает обновленную версию, когда это делается, изменяются исходные данные массивов и так далее. У меня есть 2 счетчика, один для родительского цикла, второй для дочернего, в конце, когда цикл заканчивается, он проверяет, прошел ли он через все родительские и дочерние элементы с помощью счетчика, и если да, то ответ отправляется модифицированный массив. Проблема в том, что ответ вызывается дважды каждый раз, что приводит к сбою сервера со следующей ошибкой:

    events.js:136
      throw er; // Unhandled 'error' event
      ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at validateHeader (_http_outgoing.js:503:11)
    at ServerResponse.setHeader (_http_outgoing.js:510:3)
    at ServerResponse.header (/Users/admin/Documents/projects/stalotenisas/server/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/Users/admin/Documents/projects/stalotenisas/server/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/admin/Documents/projects/stalotenisas/server/node_modules/express/lib/response.js:267:15)
    at calcStats (/Users/admin/Documents/projects/stalotenisas/server/routes/divisions.js:253:23)
    at Match.getAll (/Users/admin/Documents/projects/stalotenisas/server/routes/divisions.js:146:7)
    at model.Query.<anonymous> (/Users/admin/Documents/projects/stalotenisas/server/node_modules/mongoose/lib/model.js:3928:16)
    at /Users/admin/Documents/projects/stalotenisas/server/node_modules/kareem/index.js:297:21
    at /Users/admin/Documents/projects/stalotenisas/server/node_modules/kareem/index.js:135:16
    at process._tickCallback (internal/process/next_tick.js:150:11)
[nodemon] app crashed - waiting for file changes before starting...

код:

const divisions = [
  {
    _id: 0,
    name: 'First division',
    teams: [
      {
        name: 'Team A',
        players: [
          'John',
          'Jim',
          'Tom',
          'Jacob'
        ]
      },
      {
        name: 'Team B',
        players: [
          'John',
          'Jim',
          'Tom',
          'Jacob'
        ]
      }
    ],
    players: [],
    tournament: false
  },
  {
    _id: 1,
    name: 'Second division',
    teams: [
      {
        name: 'Team A',
        players: [
          'John',
          'Jim',
          'Tom',
          'Jacob'
        ]
      },
      {
        name: 'Team B',
        players: [
          'John',
          'Jim',
          'Tom',
          'Jacob'
        ]
      }
    ],
    players: [],
    tournament: false
  },
  {
    _id: 2,
    name: 'Third division',
    teams: [
      {
        name: 'Team A',
        players: [
          'John',
          'Jim',
          'Tom',
          'Jacob'
        ]
      },
      {
        name: 'Team B',
        players: [
          'John',
          'Jim',
          'Tom',
          'Jacob'
        ]
      }
    ],
    players: [],
    tournament: false
  }
]

calcTournamentStats = (player, division_id, callback) => {
  setTimeout(() => {
    callback(null, 'Anthony');
  }, 2000);
}

calcStats = (team, division_id, callback) => {
  setTimeout(() => {
    callback(null, 'Team F');
  }, 2000);
}

getDivisionsByLeagueId = (callback) => {
  let count = 0;
  if (divisions.length === 0) {
    return callback('error', null);
  }
  else {
    divisions.forEach((division, dindex) => {
      count++;
      let inner_count = 0;
      if (division.tournament) {
        division.players.forEach((player, index) => {
          calcTournamentStats(player, division._id, (err, result) => {
            inner_count++;
            divisions[dindex].players[index] = result;
            if (count === divisions.length && inner_count === division.players.length) {
              callback(null, 'response which should be caled once');
            }
          });
        });
      }
      else {
        division.teams.forEach((team, index) => {
          calcStats(team, division._id, (err, result) => {
            inner_count++;
            console.log(count +' - '+ divisions.length +' || '+ inner_count +' - '+ division.teams.length);
            divisions[dindex].teams[index] = result;
            if (count === divisions.length && inner_count === division.teams.length) {
              callback(null, 'response which should be caled once');
            }
          });
        });
      }
    });
  }
};

getDivisionsByLeagueId((err, res) => {
  console.log(res);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...