首页 > 解决方案 > 循环遍历对象数组时调用方法

问题描述

如何在循环遍历对象列表及其所有属性时调用方法?

目前,我正在尝试在对象的一个​​属性中执行 setTimeout(),然后在 setTimeout() 完成延迟后转到下一个属性。我还想在数组列表下方的 DOM 中附加一个 li,同时仍然在语句中打印字符串。

任何建议将不胜感激,谢谢。

这是javascript:

const lvls = {
 start: {
    lvlTitle: 'Lets Start!',
    delay: setTimeout(function () {
      console.log("On Lets Start click I am supposed to wait a few seconds and then proceed on to the next lvl..");
}, 1000)
  },
  lvl1: {
    lvlTitle: 'Drinks/Soda/water',
    statement1: 'lvl1 info...',
    statement2: 'lvl1 more info...',
    statement3: 'lvl1 more more info' && function createContent1() {
      var ul = document.querySelector('.text-container');
      var li = document.createElement('li');
      li.appendChild(document.createTextNode('more text in this new div'));
      ul.appendChild(li);
    }
   },
   lvl2: {
     lvlTitle: 'Portion Control/Meals',
     statement1: 'lvl2 info...',
     statement2: 'lvl2 more info...',
     statement3: 'lvl2 more more info' && function createContent2() {
       var ul = document.querySelector('.text-container');
       var li = document.createElement('li');
       li.appendChild(document.createTextNode('more text in this new div'));
       ul.appendChild(li);
     }
   }
 }

 function* deepValuesIterator(o) {
   if (typeof o === 'object') {
     for (const value of Object.values(o)) {
      yield* deepValuesIterator(value)
    }
    } else {
     yield o
    }
 }

 function* nextLevel(levels, generator, element) {
   while (true) {
     for (const value of generator(levels)) {
      yield element.textContent = value
     }
   }
 }

 const printText = document.querySelector('.text-container')
 const lvlsIterator = nextLevel(lvls, deepValuesIterator, printText)

 printText.addEventListener('click', () => lvlsIterator.next())

 lvlsIterator.next()

这是HTML:

<div class="full-page">
 <div class="click-container">
  <ul class="text-container">
    <li class="text-content">
      <div></div>
    </li>
  </ul>
</div>

最后这里是一个 JSFiddle: Calling Method while Looping Through Array List

标签: javascript

解决方案


如何在循环遍历对象列表及其所有属性时调用方法?

这相当简单,在迭代时只需检查属性是否为函数,如果是则调用它。

目前我正在尝试在对象的一个​​属性中执行 setTimeout(),然后在 setTimeout() 完成延迟后转到下一个属性

这里有一些误解:

  • 超时在脚本加载时开始,而不是在迭代器到达它时开始,因为它不是方法,而只是属性表达式中的函数调用。

  • 超时不会延迟任何事情。没有“阻塞 js”,javascript 通过回调解决了这样的问题,并且在本机迭代器中并不能很好地工作(目前)。但是您可以编写一个常规函数来迭代迭代器并将回调传递给每个产生的函数:


 function waitIterate(iterator) {
   var blocked = false;
   return function next() {
     if(blocked) return;
     const { value, done } = iterator.next();
     if(done) blocked = true;
     if(typeof value === "function") {
       blocked = true;
       value(() => (blocked = false, next()));
    } else { next(); }
  };
 }

那么我们如何使用它呢?像这样:

 function* stuff() {
   alert("test");
   yield function(cb) { setTimeout(cb, 1000); }
   alert("test2");
 }

 printText.addEventListener('click', waitIterate(stuff()));

您的原始代码仍然需要一些修改,这只是为了演示这个概念。


推荐阅读