Приложение перестает работать при использовании async / await с обещанием и appendChild - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь понять JS лучше и глубже, чтобы улучшить свои навыки. Итак, я написал демонстрационное приложение, которое добавляет JS, CSS и создает элементы DOM после загрузки HTML-документа. Я также добавил async / await и обещание. Когда я ожидаю, что мое обещание будет выполнено (строка 31 в коде JSFiddle), приложение перестает работать.

Похоже, я чего-то не понимаю, но я не знаю, что именно и как найти направление, что и как улучшить. Итак, мне нужен ваш совет.

Вот скрипка:

http://jsfiddle.net/k4z86nw3/9/

Теперь это работает, но, как я уже упоминал, если раскомментировать строку 31,

(await wait)();

перестанет работать.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Вы ожидаете разрешения обещания (вызов функции resolve в функции выполнения обещания). Вы должны разрешить (или отклонить в случае ошибки) свое обещание, вызвав resolve (или reject) как функцию:

let wait = new Promise((resolve, reject) => {
  setTimeout(() => {
    const someFunc = () => console.log('Already waited N sec.');
    resolve(someFunc);
  }, 1000);
});

(await wait)(); // in this line you are waiting result of promise resolving and then calling returned someFunc
0 голосов
/ 04 сентября 2018

Как показано на https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise,, необходимо вызвать функцию resolve внутри обещания.

'use strict';

function initAnimation() {
  (new WOW()).init();
}

function addCSS() {
  let cssStyleSheet = document.createElement('link');
  cssStyleSheet.rel = 'stylesheet';
  cssStyleSheet.href = 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css';
  document.head.appendChild(cssStyleSheet);
}

async function addWOW() {
  let wowScriptJS = document.createElement('script');
  wowScriptJS.src = 'https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js';
  wowScriptJS.onload = initAnimation;
  document.body.appendChild(wowScriptJS);
}

(async function run() {

  let res = await fetch('https://dl.dropboxusercontent.com/s/i6ckrkzscn6uuhq/data.json');

  addCSS();
  addWOW();

  let wait = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('Already waited N sec.');
      resolve();
    }, 1000);
  });

  await wait; // <<< === IF YOU UNCOMMENT THIS LINE, APP WILL STOP WORKING

  let jsonData = await res.json();
  let sections = jsonData.sections;

  function addNewChildToParentDOMElement({
    childDOMElementName,
    cssClasses,
    innerHTML,
    src,
    parentDOMNode
  }) {
    let childDOMElement = document.createElement(childDOMElementName);
    if (cssClasses) {
      childDOMElement.classList.add(...cssClasses);
    }
    if (innerHTML) {
      childDOMElement.innerHTML = innerHTML;
    }
    if (src) {
      childDOMElement.src = src;
    }
    parentDOMNode.appendChild(childDOMElement);
  }

  for (let i = 0; i < sections.length; i++) {
    console.warn('i==', i);
    let newDOMItem = document.createElement('div');

    addNewChildToParentDOMElement({
      childDOMElementName: 'h2',
      cssClasses: ['text-centered'],
      innerHTML: sections[i].title,
      parentDOMNode: newDOMItem
    });

    addNewChildToParentDOMElement({
      childDOMElementName: 'p',
      cssClasses: ['text-centered', 'wow', 'bounceInUp'],
      innerHTML: sections[i].desc,
      parentDOMNode: newDOMItem
    });


    let div = document.createElement('div');
    div.classList.add('img-centered');
    div.classList.add('wow');
    div.classList.add('flipInX');

    addNewChildToParentDOMElement({
      childDOMElementName: 'img',
      src: sections[i].imgURL,
      parentDOMNode: div
    });

    newDOMItem.appendChild(div);

    document.body.appendChild(newDOMItem);
  }

})();
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>aj_test</title>
  <style>
    .text-centered {
      text-align: center;
    }
    
    .img-centered {
      text-align: center;
    }
  </style>
</head>

<body>
</body>

</html>
...