JavaScript async & defer: асинхронный запуск сценария

Насколько мне известно, в элементе script атрибут async позволяет скрипту загружать асинхронно (аналогично изображениям), в то время как defer заставляет скрипт ждать до конца перед выполнением.

Предположим, у меня есть два сценария, которые нужно включить:

<script src = "library.js"></script>
<script src = "process.js"></script>

Я бы хотел, чтобы они оба работали асинхронно, и я бы хотел, чтобы process.js дождался конца, чтобы начать обработку.

Есть ли способ получить сценарий library.js для запустить асинхронно?

Примечание

Я вижу, что существует некоторое несоответствие между различными онлайн-ресурсами относительно фактической роли атрибута async.

MDN и WhatWG предполагают, что это означает, что сценарий должен выполнять асинхронно. Другие онлайн-ресурсы предлагают асинхронно нагрузка, но по-прежнему блокирует рендеринг при его выполнении.

Итак, вы хотите, чтобы library.js завершил работу до запуска process.js?

CertainPerformance 13.11.2018 06:01

@CertainPerformance Хороший момент. Да, я ожидал, что process.js будет иметь доступ к библиотеке.

Manngo 13.11.2018 06:03

@Phil Я просмотрел эту ссылку и обычно считаю MDN авторитетным. Однако другие сайты, на которые я смотрел, определенно предполагают, что async относится к сценарию загрузка.

Manngo 13.11.2018 06:07

Согласен, поэтому и удалил комментарий :)

Phil 13.11.2018 06:08

@Фил. Жалость. Я вижу, что стандарт whatwg.org также относится к сценарию выполнение… это немного сбивает с толку.

Manngo 13.11.2018 06:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
779
2

Ответы 2

И defer, и async влияют на выполнение сценария, а не на загрузку сценария. Я думаю, что путаница возникает из-за того, что некоторая документация немного неаккуратна с терминами, а термин загружен неясен относительно того, относится ли он к выборке ресурса или его выполнению.

Чтобы заставить library.js работать асинхронно, не дожидаясь загрузки документа, используйте атрибут async, а чтобы process.js ждал, пока документ не будет проанализирован, используйте defer:

<script src = "library.js" async></script>
<script src = "process.js" defer></script>

Обратите внимание, что library.js не гарантированно запускается до process.js, хотя, вероятно, будет.

Я ознакомился со спецификациями WhatWG и поднял вопрос о двусмысленности. Похоже, что asyncгрузы скрипт асинхронно, но по-прежнему выполняет синхронно.

Manngo 14.11.2018 04:33

Я нашел Последовательная загрузка скрипта в JavaScript, который может вам помочь:

(function(){
  
  //three JS files that need to be loaded one after the other
  var libs = [
    'https://code.jquery.com/jquery-3.1.1.min.js',
    'https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js',
    'https://cdnjs.cloudflare.com/ajax/libs/underscore.string/3.3.4/underscore.string.js'
  ];
  
  var injectLibFromStack = function(){
      if (libs.length > 0){
        
        //grab the next item on the stack
        var nextLib = libs.shift();
        var headTag = document.getElementsByTagName('head')[0];
        
        //create a script tag with this library
        var scriptTag = document.createElement('script');
        scriptTag.src = nextLib;
        
        //when successful, inject the next script
        scriptTag.onload = function(e){
          console.info("---> loaded: " + e.target.src);
          injectLibFromStack();
        };    
        
        //append the script tag to the <head></head>
        headTag.appendChild(scriptTag);
        console.info("injecting: " + nextLib);
      }
      else return;
  }
  
  //start script injection
  injectLibFromStack();
})();

Итак, ключ в том, что событие load запускается элементом <script>, когда все синхронные действия сценария завершены, круто

CertainPerformance 13.11.2018 07:09

Не совсем. Вопрос был по атрибутам async и defer. MDN утверждает, что скрипты, вставленные с использованием document.createElement, как в примере выше, по умолчанию выполняются асинхронно.

Manngo 13.11.2018 07:24

Другие вопросы по теме