#javascript #vue.js #asynchronous #async-await
Вопрос:
Я знаю, что этот вопрос может показаться повторяющимся, но я долго искал решение и не мог его найти.
У меня есть a method
, который решает a promise
после загрузки окна. Позже я жду этого метода в своем mounted
крючке. При маршрутизации на эту страницу ни само обещание, ни что-либо после его выполнения. Однако, если я обновлю страницу, все пройдет гладко.
В качестве примера, это мой method
:
getPosition() { return new Promise((resolve, reject) =gt; { window.addEventListener("load", () =gt; { console.log("window is loaded"); resolve(); }); }); },
Это мой mounted
крючок:
async mounted() { console.log("before promise"); // this logs await this.getPosition(); // this does not log console.log("after promise"); // this does not log },
Ответ №1:
getPosition
не гарантируется , что оно будет выполнено раньше load
, и условие гонки приведет к ожидающему обещанию. Следует дополнительно проверить, что окно уже загружено:
new Promise(resolve =gt; { if (document.readyState === 'complete') { resolve(); return; } window.addEventListener("load", () =gt; resolve()); });
load
событие происходит после загрузки всех изображений и стилей, что обычно не требуется, но приводит к дополнительной задержке. В большинстве случаев вместо этого полезно дождаться ДОМА:
new Promise(resolve =gt; { if (document.readyState !== 'loading') { resolve(); return; } document.addEventListener("DOMContentLoaded", () =gt; resolve()); });
load
и DOMContentLoaded
ожидается, что событие будет отправлено один раз при начальной загрузке страницы. Последующие изменения DOM и сетевые запросы не должны отслеживаться через них.
Комментарии:
1. Я не уверен, что здесь имеет место расовое состояние. Во-первых, я на самом деле не хочу
getPosition()
, чтобы меня казнили раньшеload
. Я хочу, чтобы он запускался при загрузке окна. И во-вторых, как ни странно, все это прекрасно работает по мере необходимости, если я просто обновляю страницу, когда она уже перенаправлена на нее. Он не работает точно, когда я направляюсь к нему. И еще, мне на самом деле нужноload
именно это. Мне нужно дождаться загрузки изображения.2. Но вы уже выполнили GetPosition после загрузки, вот причина, по которой возникает эта проблема. Под условием гонки я подразумевал, что событие загрузки уже было отправлено. Он выдается один раз при загрузке страницы. Если вы хотите отслеживать события загрузки изображения после этого, то у вас, скорее всего, проблема XY, она не должна решаться с этой стороны.
3. Так вы имеете в виду, что это
load
событие может произойти до моего звонкаgetPosition()
? Тогда почему логика работает нормально, если я просто обновляю страницу?4. ДА. Я не сказал об этом прямо в ответе, потому что это предполагается для события, так работает жизненный цикл. Это сработало, потому что страница еще не загрузилась (стабилизировалась) на момент установки приложения и выполнения начальной навигации по маршрутизатору.
load
, и т. Д. Активно использовались во времена jQuery и маршрутизации только на сервере, они на самом деле не полезны в SPA ни для чего, кроме глобальных вещей, таких как загрузка сторонних скриптов (аналитики и т. Д.) Один раз в соответствующее время.5. Не знаю почему, но не смог заставить это работать. В любом случае, спасибо за помощь.