JavaScript: Simple Asyn c Проблема - PullRequest
2 голосов
/ 26 апреля 2020

Итак, я немного новичок в асинхронном JavaScript и не могу понять, почему '.2 регистрируются перед' .1.

Единственный асинхронный метод здесь - makePokemon()

Моя цель состоит в том, чтобы все журналы «.1 до» .2. спасибо

                sender.room().forEach(async (client) => {
                    const pokemon = await makePokemon(client.getPokemon());
                    client.setPokemon(pokemon);
                    console.log('.1');
                });
                sender.room().forEach(client => {
                    console.log('.2');
                    client.emit('redirect', {
                        yourPokemon: client.getPokemon(),
                        theirPokemon: client.getOpponent().getPokemon()
                    });
                });

Ответы [ 3 ]

4 голосов
/ 26 апреля 2020

Насколько я понимаю, при использовании forEach() в браузере ожидается, что обратный вызов будет выполняться синхронно.

Однако вы можете изменить свой код следующим образом (при условии, что родительская функция объявлена ​​async ):

/* 
The following changes require the calling function to be async

async function foo() { */

/* Express iteration with for..of to achieve desired behavior */
for(const client of sender.room()) {
  
  const pokemon = await makePokemon(client.getPokemon());
  client.setPokemon(pokemon);
  console.log('.1');

}

for(const client of sender.room()) {
  console.log('.2');
  client.emit('redirect', {
    yourPokemon: client.getPokemon(),
    theirPokemon: client.getOpponent().getPokemon()
  });
}

/* } */

В качестве альтернативы, как отмечает Патрик Робертс, вы можете express эту логику c частично с Promise.all(). Одним из преимуществ этого подхода является то, что он позволяет отправлять сразу несколько async задач (ie makePokemon), а не последовательно (как в случае выше):

/* Map each client to a promise and execute all with Promise.all() */
Promise.all(sender.room().map(async(client) => {
  const pokemon = await makePokemon(client.getPokemon());
  client.setPokemon(pokemon);
  console.log('.1');
}))
/* If all prior promises are resolved, continue with next iteration */
.then(() => {

    for (const client of sender.room()) {
      console.log('.2');
      client.emit('redirect', {
        yourPokemon: client.getPokemon(),
        theirPokemon: client.getOpponent().getPokemon()
      });
    }
})
2 голосов
/ 26 апреля 2020

Попробуйте дождаться всех обещаний:

            const promises = sender.room().map(async (client) => {
                const pokemon = await makePokemon(client.getPokemon());
                client.setPokemon(pokemon);
                console.log('.1');
            });
            await Promise.all(promises);
            sender.room().forEach(client => {
                console.log('.2');
                client.emit('redirect', {
                    yourPokemon: client.getPokemon(),
                    theirPokemon: client.getOpponent().getPokemon()
                });
            });
0 голосов
/ 26 апреля 2020

forEach не будет ждать каждого l oop до конца sh, он просто запускает кучу обещаний. Если вы хотите явно дождаться всех этих обещаний до конца sh до начала второго l oop, вы можете использовать map, а затем Promise.all. map вернет массив обещаний. Promise.all будет явно приостанавливаться, пока все обещания в данном массиве не будут разрешены. Что-то подобное работает?

// use `map` and capture each promise in a new array
const pokemonPromises = sender.room().map(async (client) => {
  const pokemon = await makePokemon(client.getPokemon());
  client.setPokemon(pokemon);
  console.log('.1');
});

// explicitly wait for all promises to finish before continuing.
await Promise.all(pokemonPromises);

// Continue with non async stuff
sender.room().forEach(client => {
  console.log('.2');
  client.emit('redirect', {
    yourPokemon: client.getPokemon(),
    theirPokemon: client.getOpponent().getPokemon()
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...