Должен ли я ожидать, что этот код будет блокироваться? Есть ли способ заставить его блокировать?

#javascript #react-native #async-await

#javascript #реагировать-родной #async-await

Вопрос:

Я хотел вызвать асинхронный метод из кода верхнего уровня и наткнулся на код, похожий на приведенный ниже, в качестве решения для того, как это сделать. Похоже, что, хотя он вызывает doSomething() , он не блокируется, и приведенный ниже код продолжает выполняться до возврата doSomething() .

 // code...

(async () => await DoSomething())();

// more code...
 

После дальнейшего рассмотрения я полагаю, что понимаю, почему это будет работать таким образом. Я полагаю, я мог бы обернуть остальную часть моего кода ниже в вызов .then(), чтобы получить ожидаемое поведение, хотя это не кажется идеальным.

Можно ли написать синхронный метод CallSynchronously(asyncMethodToRun) для синхронного запуска асинхронного метода?

Примечание: я не нашел вопроса / ответа на SO, в котором конкретно говорилось бы, как сделать то, о чем я прошу, и я не видел ответа, в котором однозначно говорилось бы, что это невозможно. Но если кто-нибудь хотел бы закрыть этот вопрос как дубликат и указать на какой-то другой ответ, который дает альтернативные решения, которые меня полностью устраивают. Все, о чем я прошу, это если в ответе, на который вы указываете, конкретно не говорится, что то, о чем я просил, не может быть выполнено, что вы должны указать мне в комментарии, если это так. Потому что я буду троллить тебя до чертиков, если ты этого не сделаешь, лол. 🙂

Комментарии:

1. Асинхронные операции не синхронизированы; вот и все, их нельзя принудительно синхронизировать. Однако вы можете поставить an await перед iife.

2. @xxh Спасибо, я понял ваше первое утверждение. Не уверен, что вы имеете в виду насчет второго… даже не уверен, что iffe — это опечатка?

3. Да, исправлено.

4. Ого, извините; здесь: developer.mozilla.org/en-US/docs/Glossary/IIFE .

5. О, это код верхнего уровня !? Да, нет, время выполнить этот большой .then вызов 🙂 Есть предложение для ожидания на верхнем уровне, просто ожидая его завершения и развертывания. На самом деле, я обновляю свой ответ прямо сейчас.

Ответ №1:

Невозможно заставить асинхронную операцию выполняться синхронно.

Если бы это было возможно, основной поток никогда бы ничего не сделал.

Подумайте о получении события щелчка мыши, ожидание которого по своей сути является асинхронной операцией.

Если бы такая операция блокировала поток, сам щелчок никогда не мог быть получен, поскольку основной поток заблокирован!

Ключевая идея заключается в том, что асинхронная операция просто произойдет, она не особенно заботится о потоке выполнения вашей программы, и ваша программа тоже, вот почему существует async / await .

Иногда мы должны посмотреть, что такое async / await в JavaScript на самом деле: хороший синтаксис для того, что в противном случае было бы обратными вызовами. (помимо трассировки стека, это эквивалентно использованию .then )

На самом деле асинхронные функции синхронно возвращают объект promise .

Объект promise разрешается асинхронно.

 // code...

(async () => await DoSomething())();

// more code...
 

Если вы хотите more code дождаться вызова to DoSomething , просто удалите iife, например:

 // code...

await DoSomething();

// more code...
 

В качестве альтернативы, если в блоке есть дополнительный код, вы можете использовать await оператор перед iife:

 // code...

await (async () => await DoSomething())();

// more code...
 

(если в функции есть дополнительный код, то, вероятно, вы можете сократить его до скобок)

Если это код верхнего уровня, вы можете обернуть все это в iife:

 // code...

(async () => {
    await DoSomething();

    // more code...
})();
 

Это, безусловно, самый простой способ написания асинхронного кода верхнего уровня, и то, что я сделал лично.

Комментарии:

1. Если я чего-то не упускаю, я не могу делать то, что вы предлагаете, потому что я не могу использовать await в коде верхнего уровня. Я скажу, что одна проблема, с которой я сталкиваюсь, заключается в том, что при экспорте я не могу понять, как экспортировать асинхронную функцию. Я получаю ошибки. Я полагаю, что видел, как другие это делали. Итак, это отдельный вопрос, который я должен задать, но если у вас нет больше предложений … похоже, ответ на этот вопрос просто заключается в том, что это невозможно сделать.

2. Обновлено. Вам нужно что-то экспортировать после вызова асинхронной функции?

3. Я просто имел в виду, что мой «окончательный» экспорт по умолчанию (или как бы вы его ни назвали … тот, который в моем App.js ) в настоящее время не является асинхронным. И когда я попытался сделать его асинхронным, я получил сообщение об ошибке. Я задам другой вопрос об этом позже, если я не разберусь с этим самостоятельно. Я уже много лет являюсь разработчиком Microsoft shop с полным стеком, но только начал изучать RN пару месяцев назад, потому что, ну, Xamarin отстой по той же причине, по которой WPF отстой.

4. Как ни странно, я никогда даже не касался RN, но я понимаю весь основной язык JS. Никогда не нужно было знать RN, чтобы ответить на этот вопрос, не уверен, нужен ли ему вообще тег.

5. Правда, это скорее проблема javascript, с которой я изначально хотел пометить сообщение, но не сделал этого (просто добавил его). Рад, что вы все равно заинтересовались сообщением. 🙂