如何遍历关联数组并在数据块之间延迟呈现数据块
How to loop over an associative array and present chunks of data with a delay between chunks
我正在努力在页面上呈现生日。我想要实现的是将部门作为标题,然后在其下显示 3 个生日并循环遍历部门直到显示所有生日(延迟 5 秒以便可以阅读),然后继续下一个部门.
我在 jsFiddle 上有一个示例,这是我的大部分代码:
$.wait(3000, function() {
$(".action-area").animate({
'visibility': 'visible'
}, 2000, function() {
$(".action-area").fadeIn().removeClass('hidden');
presentMultipleData(_birthdayData, 5);
});
});
var _chunkLimit = 3;
function presentMultipleData(data, limit) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
// Chunk out the array to only show a specific count
var chunkArray = chunk(_chunkLimit, data[key]);
$("h1.department").text(key);
// Chunk group
for (var i = 0, len = chunkArray.length; i < len; i++) {
// Empty for new group to be shown
$("#item-list").empty();
// Add group items
_addGroupItems(chunkArray[i]);
// @todo Need to delay after each chunk is added so it is presented for 5 seconds
// then go to the next group
}
}
}
}
function _addGroupItems(data) {
for (var i = 0, len = data.length; i < len; i++) {
var _item = buildItem(data[i]);
$("#item-list").append(_item);
}
}
function buildItem(row) {
var _item = $('<div/>', {
'class':'item',
'text': row['name']+' - '+row['date'],
});
return _item;
}
function chunk(chunkSize, array) {
return array.reduce(function(previous, current) {
var chunk;
if (previous.length === 0 || previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []);
}
我能够循环遍历所有内容,构建项目并呈现它们的逻辑是...我遇到的问题是延迟 5 秒然后继续。
我认为是 for 循环导致了这里的问题,因为我更多地研究了 Promises 和 Deffered 示例。我在 SO 上看到了很多关于此类事情的主题,但看不到一个可以满足我的需求的主题。
正如您在我的演示中看到的那样,它运行了,但您唯一看到的是最后的结果,即最后一个部门和最后 3 个人。我尝试了多种不同的方法,并已将它们从代码中清除,因为没有任何效果。我有一段时间没有使用 JavaScript 所以当我尝试使用 Promises 时我没有成功,不确定它们是否应该以这种方式使用。
我只需要在正确的方向上推动这一点。希望这里有人可以提供帮助。谢谢
你可以使用 Promise 和 array#reduce
来实现你想要的
reduce 回调的每次迭代 returns 承诺在 5 秒后解决。这个承诺的回调 "waits" 就像 promise.then(....)
(承诺是在上一次迭代中返回的承诺
你本质上是一个数组中的数组,所以你将 "chunks" reduce 嵌套在 "departments" reduce
中
当整个事情完成时,工作片段还会记录 "all done" 到控制台。这是通过从外部 reduce 返回承诺,并将 .then 添加到 presentMultipleData
调用
来实现的
var _birthdayData = JSON.parse('{"Admin Operations":[{"name":"Blanca Tirado","date":"08\/26","department":"Admin Operations","position":"Reporter"}],"Customer Service":[{"name":"Perla Mendoza","date":"08\/26","department":"Customer Service","position":"Receptionist"},{"name":"Jeanette Lopez","date":"08\/30","department":"Customer Service","position":"Customer Service Rep"}],"Onion AM":[{"name":"Eutimio Merida","date":"08\/28","department":"Onion AM","position":"Onion Peeler"}],"Prep":[{"name":"Carlos Segovia","date":"08\/27","department":"Prep","position":"WIP"},{"name":"Margarita Rodriguez","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Orlin Fuentes Nunes","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Fairy Garcia","date":"09\/04","department":"Prep","position":"WIP"},{"name":"Mireya Lomeli","date":"09\/09","department":"Prep","position":"WIP"}],"Production 1":[{"name":"Jesus Alvarado","date":"09\/01","department":"Production 1","position":"Line Worker"},{"name":"Rosa Jimenez","date":"09\/03","department":"Production 1","position":"Line Worker"},{"name":"Natividad Jacuinde","date":"09\/08","department":"Production 1","position":"Line Worker"}],"Production 2":[{"name":"Juventino Sanchez","date":"09\/01","department":"Production 2","position":"Equipment Operator"},{"name":"Deysi Garcia","date":"09\/02","department":"Production 2","position":"Specialist"},{"name":"Aristeo Medina","date":"09\/03","department":"Production 2","position":"Line Worker"}],"Quality Assurance":[{"name":"Martha Lopez","date":"08\/31","department":"Quality Assurance","position":"QA Tech 2"},{"name":"Juana Robledo","date":"09\/01","department":"Quality Assurance","position":"QA Tech 2"}],"Retail B":[{"name":"Luz Cruz","date":"08\/26","department":"Retail B","position":"Specialist"}],"Retail C":[{"name":"Rosalina Lopez","date":"08\/30","department":"Retail C","position":"Specialist"}],"Sanitation":[{"name":"Yajaira Medina","date":"08\/26","department":"Sanitation","position":"Sanitation Tech 1"},{"name":"Luis Mendez Lopez","date":"08\/31","department":"Sanitation","position":"Sanitation Tech 1"}],"Warehouse":[{"name":"Ramon Cardenas","date":"08\/27","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Ramon Amezquita","date":"08\/28","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Juan Sayula","date":"09\/02","department":"Warehouse","position":"Shipping Tech"}]}');
jQuery(function($) {
$.wait = function(duration, completeCallback, target) {
$target = $(target || '<queue />');
return $target.delay(duration).queue(function(next){completeCallback.call($target); next();});
}
$.fn.wait = function(duration, completeCallback) {
return $.wait.call(this, duration, completeCallback, this);
};
$.wait(3000, function() {
$(".action-area").animate({
'visibility': 'visible'
}, 2000, function() {
$(".action-area").fadeIn().removeClass('hidden');
presentMultipleData(_birthdayData, 5).then(function() {
console.log('all done');
});
});
});
var _chunkLimit = 3;
function presentMultipleData(data, limit) {
var pdelay = function() {
return new Promise(function(resolve) {
setTimeout(resolve, 5000);
})
};
return Object.keys(data).reduce(function(promise, key) {
return promise.then(function() {
// Chunk out the array to only show a specific count
var chunkArray = chunk(_chunkLimit, data[key]);
$("h1.department").text(key);
return chunkArray.reduce(function(promise, chunk) {
return promise.then(function() {
$("#item-list").empty();
_addGroupItems(chunk);
return pdelay();
});
}, Promise.resolve());
});
}, Promise.resolve());
}
function _addGroupItems(data) {
for (var i = 0, len = data.length; i < len; i++) {
var _item = buildItem(data[i]);
$("#item-list").append(_item);
}
}
function buildItem(row) {
var _item = $('<div/>', {
'class':'item',
'text': row['name']+' - '+row['date'],
});
return _item;
}
function chunk(chunkSize, array) {
return array.reduce(function(previous, current) {
var chunk;
if (previous.length === 0 || previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cage">
<div class="action-area hidden">
<div class="modal-window">
<h1 class="department"></h1>
<div id="item-list" class="modal-content"></div>
</div>
</div>
</div>
non jquery, es2015+ version
var _birthdayData = JSON.parse('{"Admin Operations":[{"name":"Blanca Tirado","date":"08\/26","department":"Admin Operations","position":"Reporter"}],"Customer Service":[{"name":"Perla Mendoza","date":"08\/26","department":"Customer Service","position":"Receptionist"},{"name":"Jeanette Lopez","date":"08\/30","department":"Customer Service","position":"Customer Service Rep"}],"Onion AM":[{"name":"Eutimio Merida","date":"08\/28","department":"Onion AM","position":"Onion Peeler"}],"Prep":[{"name":"Carlos Segovia","date":"08\/27","department":"Prep","position":"WIP"},{"name":"Margarita Rodriguez","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Orlin Fuentes Nunes","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Fairy Garcia","date":"09\/04","department":"Prep","position":"WIP"},{"name":"Mireya Lomeli","date":"09\/09","department":"Prep","position":"WIP"}],"Production 1":[{"name":"Jesus Alvarado","date":"09\/01","department":"Production 1","position":"Line Worker"},{"name":"Rosa Jimenez","date":"09\/03","department":"Production 1","position":"Line Worker"},{"name":"Natividad Jacuinde","date":"09\/08","department":"Production 1","position":"Line Worker"}],"Production 2":[{"name":"Juventino Sanchez","date":"09\/01","department":"Production 2","position":"Equipment Operator"},{"name":"Deysi Garcia","date":"09\/02","department":"Production 2","position":"Specialist"},{"name":"Aristeo Medina","date":"09\/03","department":"Production 2","position":"Line Worker"}],"Quality Assurance":[{"name":"Martha Lopez","date":"08\/31","department":"Quality Assurance","position":"QA Tech 2"},{"name":"Juana Robledo","date":"09\/01","department":"Quality Assurance","position":"QA Tech 2"}],"Retail B":[{"name":"Luz Cruz","date":"08\/26","department":"Retail B","position":"Specialist"}],"Retail C":[{"name":"Rosalina Lopez","date":"08\/30","department":"Retail C","position":"Specialist"}],"Sanitation":[{"name":"Yajaira Medina","date":"08\/26","department":"Sanitation","position":"Sanitation Tech 1"},{"name":"Luis Mendez Lopez","date":"08\/31","department":"Sanitation","position":"Sanitation Tech 1"}],"Warehouse":[{"name":"Ramon Cardenas","date":"08\/27","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Ramon Amezquita","date":"08\/28","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Juan Sayula","date":"09\/02","department":"Warehouse","position":"Shipping Tech"}]}');
document.addEventListener("DOMContentLoaded", e => {
var _chunkLimit = 3,
pdelay = timeout => new Promise(resolve => setTimeout(resolve, timeout)),
buildItem = row => {
var div = document.createElement('div');
div.classname = 'item';
div.appendChild(document.createTextNode(row.name+' - '+row.date));
return div;
},
_addGroupItems = data => data.map(item => buildItem(item)).forEach(item => document.getElementById("item-list").appendChild(item)),
toChunk = (chunkSize, array) => array.reduce((previous, current) => {
var chunk;
if (previous.length === 0 || previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []),
presentMultipleData = (data, limit) => Object.keys(data).reduce((promise, key) => promise.then(() => {
// Chunk out the array to only show a specific count
var chunkArray = toChunk(_chunkLimit, data[key]);
document.querySelector("h1.department").textContent = key;
return chunkArray.reduce((promise, chunk) => promise.then(() => {
document.getElementById("item-list").innerHTML = '';
_addGroupItems(chunk);
return pdelay(5000);
}), Promise.resolve());
}), pdelay(5000));
presentMultipleData(_birthdayData, 5).then(() => console.log('all done'));
});
<div id="cage">
<div class="action-area hidden">
<div class="modal-window">
<h1 class="department"></h1>
<div id="item-list" class="modal-content"></div>
</div>
</div>
</div>
我正在努力在页面上呈现生日。我想要实现的是将部门作为标题,然后在其下显示 3 个生日并循环遍历部门直到显示所有生日(延迟 5 秒以便可以阅读),然后继续下一个部门.
我在 jsFiddle 上有一个示例,这是我的大部分代码:
$.wait(3000, function() {
$(".action-area").animate({
'visibility': 'visible'
}, 2000, function() {
$(".action-area").fadeIn().removeClass('hidden');
presentMultipleData(_birthdayData, 5);
});
});
var _chunkLimit = 3;
function presentMultipleData(data, limit) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
// Chunk out the array to only show a specific count
var chunkArray = chunk(_chunkLimit, data[key]);
$("h1.department").text(key);
// Chunk group
for (var i = 0, len = chunkArray.length; i < len; i++) {
// Empty for new group to be shown
$("#item-list").empty();
// Add group items
_addGroupItems(chunkArray[i]);
// @todo Need to delay after each chunk is added so it is presented for 5 seconds
// then go to the next group
}
}
}
}
function _addGroupItems(data) {
for (var i = 0, len = data.length; i < len; i++) {
var _item = buildItem(data[i]);
$("#item-list").append(_item);
}
}
function buildItem(row) {
var _item = $('<div/>', {
'class':'item',
'text': row['name']+' - '+row['date'],
});
return _item;
}
function chunk(chunkSize, array) {
return array.reduce(function(previous, current) {
var chunk;
if (previous.length === 0 || previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []);
}
我能够循环遍历所有内容,构建项目并呈现它们的逻辑是...我遇到的问题是延迟 5 秒然后继续。
我认为是 for 循环导致了这里的问题,因为我更多地研究了 Promises 和 Deffered 示例。我在 SO 上看到了很多关于此类事情的主题,但看不到一个可以满足我的需求的主题。
正如您在我的演示中看到的那样,它运行了,但您唯一看到的是最后的结果,即最后一个部门和最后 3 个人。我尝试了多种不同的方法,并已将它们从代码中清除,因为没有任何效果。我有一段时间没有使用 JavaScript 所以当我尝试使用 Promises 时我没有成功,不确定它们是否应该以这种方式使用。
我只需要在正确的方向上推动这一点。希望这里有人可以提供帮助。谢谢
你可以使用 Promise 和 array#reduce
来实现你想要的reduce 回调的每次迭代 returns 承诺在 5 秒后解决。这个承诺的回调 "waits" 就像 promise.then(....)
(承诺是在上一次迭代中返回的承诺
你本质上是一个数组中的数组,所以你将 "chunks" reduce 嵌套在 "departments" reduce
中当整个事情完成时,工作片段还会记录 "all done" 到控制台。这是通过从外部 reduce 返回承诺,并将 .then 添加到 presentMultipleData
调用
var _birthdayData = JSON.parse('{"Admin Operations":[{"name":"Blanca Tirado","date":"08\/26","department":"Admin Operations","position":"Reporter"}],"Customer Service":[{"name":"Perla Mendoza","date":"08\/26","department":"Customer Service","position":"Receptionist"},{"name":"Jeanette Lopez","date":"08\/30","department":"Customer Service","position":"Customer Service Rep"}],"Onion AM":[{"name":"Eutimio Merida","date":"08\/28","department":"Onion AM","position":"Onion Peeler"}],"Prep":[{"name":"Carlos Segovia","date":"08\/27","department":"Prep","position":"WIP"},{"name":"Margarita Rodriguez","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Orlin Fuentes Nunes","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Fairy Garcia","date":"09\/04","department":"Prep","position":"WIP"},{"name":"Mireya Lomeli","date":"09\/09","department":"Prep","position":"WIP"}],"Production 1":[{"name":"Jesus Alvarado","date":"09\/01","department":"Production 1","position":"Line Worker"},{"name":"Rosa Jimenez","date":"09\/03","department":"Production 1","position":"Line Worker"},{"name":"Natividad Jacuinde","date":"09\/08","department":"Production 1","position":"Line Worker"}],"Production 2":[{"name":"Juventino Sanchez","date":"09\/01","department":"Production 2","position":"Equipment Operator"},{"name":"Deysi Garcia","date":"09\/02","department":"Production 2","position":"Specialist"},{"name":"Aristeo Medina","date":"09\/03","department":"Production 2","position":"Line Worker"}],"Quality Assurance":[{"name":"Martha Lopez","date":"08\/31","department":"Quality Assurance","position":"QA Tech 2"},{"name":"Juana Robledo","date":"09\/01","department":"Quality Assurance","position":"QA Tech 2"}],"Retail B":[{"name":"Luz Cruz","date":"08\/26","department":"Retail B","position":"Specialist"}],"Retail C":[{"name":"Rosalina Lopez","date":"08\/30","department":"Retail C","position":"Specialist"}],"Sanitation":[{"name":"Yajaira Medina","date":"08\/26","department":"Sanitation","position":"Sanitation Tech 1"},{"name":"Luis Mendez Lopez","date":"08\/31","department":"Sanitation","position":"Sanitation Tech 1"}],"Warehouse":[{"name":"Ramon Cardenas","date":"08\/27","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Ramon Amezquita","date":"08\/28","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Juan Sayula","date":"09\/02","department":"Warehouse","position":"Shipping Tech"}]}');
jQuery(function($) {
$.wait = function(duration, completeCallback, target) {
$target = $(target || '<queue />');
return $target.delay(duration).queue(function(next){completeCallback.call($target); next();});
}
$.fn.wait = function(duration, completeCallback) {
return $.wait.call(this, duration, completeCallback, this);
};
$.wait(3000, function() {
$(".action-area").animate({
'visibility': 'visible'
}, 2000, function() {
$(".action-area").fadeIn().removeClass('hidden');
presentMultipleData(_birthdayData, 5).then(function() {
console.log('all done');
});
});
});
var _chunkLimit = 3;
function presentMultipleData(data, limit) {
var pdelay = function() {
return new Promise(function(resolve) {
setTimeout(resolve, 5000);
})
};
return Object.keys(data).reduce(function(promise, key) {
return promise.then(function() {
// Chunk out the array to only show a specific count
var chunkArray = chunk(_chunkLimit, data[key]);
$("h1.department").text(key);
return chunkArray.reduce(function(promise, chunk) {
return promise.then(function() {
$("#item-list").empty();
_addGroupItems(chunk);
return pdelay();
});
}, Promise.resolve());
});
}, Promise.resolve());
}
function _addGroupItems(data) {
for (var i = 0, len = data.length; i < len; i++) {
var _item = buildItem(data[i]);
$("#item-list").append(_item);
}
}
function buildItem(row) {
var _item = $('<div/>', {
'class':'item',
'text': row['name']+' - '+row['date'],
});
return _item;
}
function chunk(chunkSize, array) {
return array.reduce(function(previous, current) {
var chunk;
if (previous.length === 0 || previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cage">
<div class="action-area hidden">
<div class="modal-window">
<h1 class="department"></h1>
<div id="item-list" class="modal-content"></div>
</div>
</div>
</div>
non jquery, es2015+ version
var _birthdayData = JSON.parse('{"Admin Operations":[{"name":"Blanca Tirado","date":"08\/26","department":"Admin Operations","position":"Reporter"}],"Customer Service":[{"name":"Perla Mendoza","date":"08\/26","department":"Customer Service","position":"Receptionist"},{"name":"Jeanette Lopez","date":"08\/30","department":"Customer Service","position":"Customer Service Rep"}],"Onion AM":[{"name":"Eutimio Merida","date":"08\/28","department":"Onion AM","position":"Onion Peeler"}],"Prep":[{"name":"Carlos Segovia","date":"08\/27","department":"Prep","position":"WIP"},{"name":"Margarita Rodriguez","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Orlin Fuentes Nunes","date":"08\/29","department":"Prep","position":"WIP"},{"name":"Fairy Garcia","date":"09\/04","department":"Prep","position":"WIP"},{"name":"Mireya Lomeli","date":"09\/09","department":"Prep","position":"WIP"}],"Production 1":[{"name":"Jesus Alvarado","date":"09\/01","department":"Production 1","position":"Line Worker"},{"name":"Rosa Jimenez","date":"09\/03","department":"Production 1","position":"Line Worker"},{"name":"Natividad Jacuinde","date":"09\/08","department":"Production 1","position":"Line Worker"}],"Production 2":[{"name":"Juventino Sanchez","date":"09\/01","department":"Production 2","position":"Equipment Operator"},{"name":"Deysi Garcia","date":"09\/02","department":"Production 2","position":"Specialist"},{"name":"Aristeo Medina","date":"09\/03","department":"Production 2","position":"Line Worker"}],"Quality Assurance":[{"name":"Martha Lopez","date":"08\/31","department":"Quality Assurance","position":"QA Tech 2"},{"name":"Juana Robledo","date":"09\/01","department":"Quality Assurance","position":"QA Tech 2"}],"Retail B":[{"name":"Luz Cruz","date":"08\/26","department":"Retail B","position":"Specialist"}],"Retail C":[{"name":"Rosalina Lopez","date":"08\/30","department":"Retail C","position":"Specialist"}],"Sanitation":[{"name":"Yajaira Medina","date":"08\/26","department":"Sanitation","position":"Sanitation Tech 1"},{"name":"Luis Mendez Lopez","date":"08\/31","department":"Sanitation","position":"Sanitation Tech 1"}],"Warehouse":[{"name":"Ramon Cardenas","date":"08\/27","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Ramon Amezquita","date":"08\/28","department":"Warehouse","position":"Warehouse Tech 1"},{"name":"Juan Sayula","date":"09\/02","department":"Warehouse","position":"Shipping Tech"}]}');
document.addEventListener("DOMContentLoaded", e => {
var _chunkLimit = 3,
pdelay = timeout => new Promise(resolve => setTimeout(resolve, timeout)),
buildItem = row => {
var div = document.createElement('div');
div.classname = 'item';
div.appendChild(document.createTextNode(row.name+' - '+row.date));
return div;
},
_addGroupItems = data => data.map(item => buildItem(item)).forEach(item => document.getElementById("item-list").appendChild(item)),
toChunk = (chunkSize, array) => array.reduce((previous, current) => {
var chunk;
if (previous.length === 0 || previous[previous.length -1].length === chunkSize) {
chunk = [];
previous.push(chunk);
}
else {
chunk = previous[previous.length -1];
}
chunk.push(current);
return previous;
}, []),
presentMultipleData = (data, limit) => Object.keys(data).reduce((promise, key) => promise.then(() => {
// Chunk out the array to only show a specific count
var chunkArray = toChunk(_chunkLimit, data[key]);
document.querySelector("h1.department").textContent = key;
return chunkArray.reduce((promise, chunk) => promise.then(() => {
document.getElementById("item-list").innerHTML = '';
_addGroupItems(chunk);
return pdelay(5000);
}), Promise.resolve());
}), pdelay(5000));
presentMultipleData(_birthdayData, 5).then(() => console.log('all done'));
});
<div id="cage">
<div class="action-area hidden">
<div class="modal-window">
<h1 class="department"></h1>
<div id="item-list" class="modal-content"></div>
</div>
</div>
</div>