Javascript - дождаться асин c вызова fini sh, прежде чем вернуться из функции, без использования обратных вызовов - PullRequest
0 голосов
/ 23 апреля 2020

Я хочу предисловие, сказав, что я просмотрел много вопросов о стековом потоке, касающихся этой топики c, но я не нашел «дубликатов» как таковых, так как ни один из них не содержит решений, которые могли бы решить эту проблему c case.

Я в основном смотрел на Как мне вернуть ответ от асинхронного вызова? , и раздел «Обещания с асинхронным / ожидающим» будет работать внутри асинхронной функции , но функция, над которой я работаю, не asyn c и является частью существующей кодовой базы, которую я не могу легко изменить. Я не смог бы изменить функцию на asyn c.

Секция обратных вызовов также не будет работать, что будет объяснено ниже. В любом случае, я перейду к своему вопросу:

Я редактирую функцию (стандартная функция, а не asyn c) в JavaScript, добавляя асинхронный вызов функции. Я хочу подождать, пока вызов asyn c завершится, прежде чем я вернусь из функции (поскольку результат вызова asyn c должен быть включен в возвращаемое значение). Как мне это сделать?

Я изучил использование обратных вызовов, которые позволили бы мне написать код, который гарантированно будет работать только после завершения вызова asyn c. Однако это не будет прерывать поток программы в исходной функции, и исходная функция все еще может вернуться до запуска обратного вызова. Обратный вызов позволил бы мне выполнить что-то последовательно после асинхронной функции c, но не позволил бы мне ожидать завершения асинхронного вызова на самом высоком уровне.

Пример кода, который не возвращался желаемый результат:

function getPlayers() {
    ... other code ...

    let outfieldPlayers = asyncGetOutfieldPlayersCall()

    ... other code ...

    allPlayers.add(outfieldPlayers)

    return allPlayers  // the returned value may or may not include outfield players
}

Реальная проблема, с которой я сталкиваюсь, немного сложнее - я вызываю функцию asyn c в каждой итерации a для l oop, и мне нужно дождитесь завершения всех вызовов, прежде чем вернуться. Но я думаю, что если я смогу решить эту более простую проблему, я смогу решить эту проблему с помощью a для l oop.

1 Ответ

2 голосов
/ 23 апреля 2020

К сожалению, практически невозможно ожидать асинхронного кода c синхронно. Это связано с тем, что в JS нет потоков (большинство JS сред выполнения, но некоторые ). Таким образом, код является либо синхронным, либо асинхронным.

Асинхронный код возможен из-за события l oop. Событие l oop является частью javascript среды выполнения . Он работает, сохраняя стек функций обратного вызова, которые запускаются, когда их запускают события - обычно это либо события тайм-аута (которые вы можете установить с помощью setTimeout()), либо события IO (которые происходят, когда вы делаете запросы на диск или HTTP, или на взаимодействие с пользователем). Однако эти обратные вызовы запускаются только тогда, когда никакой другой код не выполняет , поэтому только когда программа находится в режиме ожидания и все функции возвращены.

Это означает, что такие методы, как «циклы вращения» (где вы просто запускаете al oop, пока условие не будет изменено другим потоком), которые работают в многопоточных средах, не работают, потому что асин c код выиграл не будет работать, пока вращение l oop не закончится.

Подробнее: https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4

...