Gavr_Gavr
@Gavr_Gavr

Как правильно работать с Promise?

Есть функция загрузки скрипта:
function loadScript(src) {
      return new Promise((resolve, reject) => {
         const script = document.createElement("script");
         script.src = src;
         script.onload = () => resolve(script);
         script.onerror = () => reject(new Error(`Script load error for ${src}`));
         document.head.appendChild(script);
      });
   }


Ну и собственно сама загрузка скриптов:
loadScript("https://learn.javascript.ru/article/promise-chaining/one.js")
  .then(script => loadScript("https://learn.javascript.ru/article/promise-chaining/two.js"))
  .then(script => loadScript("https://learn.javascript.ru/article/promise-chaining/three.js"))
  .then(script => {
    one();
    two();
    three();
  });


Я не могу до конца понять две вещи:
1) Вот это присваивание script.onload = () => resolve(script); почему присваивается через функцию? Мы же можем просто присвоить так: script.onload = resolve; и записать вызов функции таким образом:
loadScript("https://learn.javascript.ru/article/promise-chaining/one.js")
      .then( () => loadScript("https://learn.javascript.ru/article/promise-chaining/two.js"))
      .then( () => loadScript("https://learn.javascript.ru/article/promise-chaining/three.js"))
      .then( () => {one()})
      .then( () => {two()})
      .then( () => {three()});


Вопрос если разница в таких записях?

2) Если resolve это функция колбек то почему такой ее вызов дает ошибку script.onload = resolve(script);, а если запихнуть в функцию стрелку script.onload = () => resolve(script); то нормально работает?
  • Вопрос задан
  • 181 просмотр
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Вопрос если разница в таких записях?

Только в передаваемом значении:
  • resolve(script) передаст дальше по цепочке этот script (который никому не нужен, похоже).
  • script.onload = resolve передаст по цепочке объект события (тоже всем по барабану)

почему такой ее вызов дает ошибку script.onload = resolve(script);
потому, что нужна функция, которую вызовут позже, а не мгновенный результат её выполнения.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Alexandroppolus
@Alexandroppolus
кодир
можно грузить параллельно, если они не зависят друг от друга и последовательность загрузки не важна

await Promise.all([
    'https://learn.javascript.ru/article/promise-chaining/one.js',
    'https://learn.javascript.ru/article/promise-chaining/two.js',
    'https://learn.javascript.ru/article/promise-chaining/three.js',
].map(loadScript));

one();
two();
three();
Ответ написан
Комментировать
zkrvndm
@zkrvndm
Архитектор решений
А теперь оцени как все это проще делается с использованием async / await:
await $.getScript('https://learn.javascript.ru/article/promise-chaining/one.js');
await $.getScript('https://learn.javascript.ru/article/promise-chaining/two.js');
await $.getScript('https://learn.javascript.ru/article/promise-chaining/three.js');

Вместо $.getScript можешь loadScript использовать, результат будет такой же - последовательная загрузка.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы