javascript - 循环遍历对象数组时调用方法
问题描述
如何在循环遍历对象列表及其所有属性时调用方法?
目前,我正在尝试在对象的一个属性中执行 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
解决方案
如何在循环遍历对象列表及其所有属性时调用方法?
这相当简单,在迭代时只需检查属性是否为函数,如果是则调用它。
目前我正在尝试在对象的一个属性中执行 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()));
您的原始代码仍然需要一些修改,这只是为了演示这个概念。
推荐阅读
- .net - 如何让 ClientAcknowledgement 在 NMS 中工作?
- google-bigquery - 如何根据 bigquery 中的时区列将 UTC 时间转换为本地时区?
- java - 如何通过隐式意图创建内容提供程序以将 PDF 文件共享到另一个应用程序?
- c++ - 非虚拟多重继承示例
- javascript - 由于 iOS 上的商店数量,PouchDB 速度变慢
- javascript - 如何使用 Google Cloud Function 有效删除旧的 Firebase Cloud 文档?
- sbt - 为什么 sbt 教程添加插件失败?
- functional-programming - 如何在 OCaml/ReasonML 中声明函数参数?
- python - 如何将 Nifti 图像中的标题信息写入 csv?
- reactjs - reactjs 应用程序添加到现有的 reactjs 应用程序