遍历对象数组时的调用方法

时间:2018-07-28 19:24:37

标签: javascript

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

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

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

这是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

2 个答案:

答案 0 :(得分:0)

函数具有不同的类型,因此您的代码没有调用函数。

我在您的deepValuesIterator函数中添加了函数结帐功能。

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

Link to fiddle

答案 1 :(得分:0)

  

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

那非常简单,在迭代时只需检查该属性是否是一个函数,是否可以调用它即可。

  

此刻,我正在尝试在对象的其中一个属性中执行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()));

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