当使用带有promise和appendChild的async / await时,应用程序停止工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当使用带有promise和appendChild的async / await时,应用程序停止工作相关的知识,希望对你有一定的参考价值。

我正在努力更好更深入地理解JS,以提高我的技能。所以,我编写了一个演示应用程序,它添加了JS,CSS并在加载html文档后创建了DOM元素。我还添加了async / await和promise。当我等待我的承诺得到解决时(JSFiddle代码中的第31行),应用程序停止工作。

看起来我不明白,但我不知道究竟是什么以及如何找到方向,改进方法和方法。所以,我需要你的建议。

这是小提琴:

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

现在它有效,但是,正如我已经提到的,如果你取消注释第31行,

(await wait)();

它会停止工作。

答案

正如在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>
另一答案

您正在等待承诺解析(在promise执行函数中调用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

以上是关于当使用带有promise和appendChild的async / await时,应用程序停止工作的主要内容,如果未能解决你的问题,请参考以下文章

带有节点 appendChild() html 的动画

带有 std::promise 的 C++11 分段错误

如何使用nodejs pg-promise库将带有uuid数组的记录插入pg表

appendChild 不能在 IE 中使用 window.open

带有 API 和数据库查询的 Node.js Promise Chain

使用带有 promise 的“map”返回有序和无序的结果