Единственная проблема с обещаниями заключается в том, что IE их не поддерживает. Edge делает, но есть много IE 10 и 11 там: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise (совместимость внизу)
Итак, JavaScript однопоточный. Если вы не делаете асинхронный вызов, он будет вести себя предсказуемо. Основной поток JavaScript выполнит одну функцию полностью перед выполнением следующей, в порядке их появления в коде. Гарантировать порядок для синхронных функций тривиально - каждая функция будет выполняться полностью в том порядке, в котором она была вызвана.
Думайте о синхронной функции как об элементарной единице работы . Основной поток JavaScript выполнит его полностью в порядке появления операторов в коде.
Но добавьте асинхронный вызов, как в следующей ситуации:
showLoadingDiv(); // function 1
makeAjaxCall(); // function 2 - contains async ajax call
hideLoadingDiv(); // function 3
Это не делает то, что вы хотите . Он мгновенно выполняет функцию 1, функцию 2 и функцию 3. Загрузка div мигает, и он исчезает, в то время как вызов ajax почти не завершен, хотя makeAjaxCall()
и вернулся. Осложнение состоит в том, что makeAjaxCall()
его работа разбита на куски, которые постепенно продвигаются при каждом вращении основного потока JavaScript - он ведет себя асинхронно. Но тот же основной поток за один оборот / прогон выполнил синхронные части быстро и предсказуемо.
Итак, способ, которым я справился : Как я уже сказал, функция - это атомная единица работы. Я объединил код функции 1 и 2 - я поместил код функции 1 в функцию 2 перед асинхронным вызовом. Я избавился от функции 1. Все до асинхронного вызова, включая асинхронный вызов, выполняется предсказуемо, по порядку.
ТОГДА, когда асинхронный вызов завершается после нескольких вращений основного потока JavaScript, он вызывает функцию 3. Это гарантирует порядок . Например, в ajax обработчик события onreadystatechange вызывается несколько раз. Когда он сообщит о завершении, вызовите последнюю функцию, которую вы хотите.
Я согласен, что это грязнее. Мне нравится, когда код должен быть симметричным, мне нравится, когда функции выполняют одно (или близко к нему), и мне не нравится, когда вызов ajax каким-либо образом отвечает за отображение (создание зависимости от вызывающего). НО, с асинхронным вызовом, встроенным в синхронную функцию, должны быть достигнуты компромиссы, чтобы гарантировать порядок выполнения. И я должен написать для IE 10, так что никаких обещаний.
Резюме : для синхронных звонков гарантированный порядок тривиален. Каждая функция выполняется полностью в том порядке, в котором она была вызвана. Для функции с асинхронным вызовом единственный способ гарантировать порядок - следить за завершением асинхронного вызова и вызывать третью функцию при обнаружении этого состояния.
Для обсуждения потоков JavaScript см. Https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23 и https://developer.mozilla.org/en-US/docs/Web/JavaScript/. EventLoop
Кроме того, еще один похожий, высоко оцененный вопрос на эту тему: как я должен вызывать 3 функции, чтобы выполнять их одну за другой?
firstFunction
именно делает это асинхронным? В любом случае - проверьте об обещаниях