到目前为止,我还没有找到令人满意的解决办法。下面是高级别的代码。
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9],
o = {a:1, b:2, c:3, d:10, e:11, f:12, g:7, h:8, i:9};
function matched(i, j) {
return a[i]===o[j];
}
for (var i=0; i<a.length; ++i) {
for (var j in o) {
if (matched(i, j)) console.log(a[i]);
}
}我有一个数组和一个对象。我正在遍历数组,然后遍历对象,通过函数matched()查找匹配,该函数返回布尔值true或false。如果条件为true,则记录数组项。如果现在运行代码(https://jsfiddle.net/thdoan/0tubbokj/),您应该会看到输出到控制台的数字1-3和7-9。
我想要做的是在每个数字之间以一秒的延迟输出数字。我知道如何在每次循环迭代之间引入延迟,但我只想为打印的数字添加延迟(即当matched()返回true时)。
Clarification:当前的解决方案(我对此不满意)是将匹配的项保存到单独的数组中,并延迟遍历该数组,但我正在寻找一个不需要创建新数组的解决方案。
发布于 2016-09-19 08:30:51
我想要做的是在每个数字之间以一秒的延迟输出数字。
你还在评论中说:
...in是真正的应用程序,匹配的程序集可能会变得非常大,所以如果有一个不需要输出到第三个数组的解决方案,我宁愿不消耗更多的内存。
要实现这两个目标,您必须完全放弃您的for循环,而要执行一个链接的setTimeout系列。
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9],
o = {a:1, b:2, c:3, d:10, e:11, f:12, g:7, h:8, i:9};
function matched(i, j) {
return a[i]===o[j];
}
// Get the property names in `o`, and start at the beginning
var keys = Object.keys(o);
var i = 0;
var keyIndex = 0;
tick();
function tick() {
// Get the "j" value for this tick
var j = keys[keyIndex];
// Is this a match?
var flag = matched(i, j);
if (flag) {
console.log(a[i]);
}
// Move to the next entry in our nested loops
if (++keyIndex >= keys.length) {
keyIndex = 0;
if (++i >= a.length) {
// Done
return;
}
}
// Continue
if (flag) {
// We output one, wait a second before next
setTimeout(tick, 1000);
} else {
// No output, continue immediately
tick(); // SEE NOTE BELOW
}
}
注意:如果一列中可能有数千个不匹配项,您可以考虑在tick中使用一个循环而不是链接到它。就ES2015而言,JavaScript应该有尾部调用优化,并且我们的tick不必将自己推到堆栈上(它只会回调到开始),但是一些JavaScript引擎还没有实现TCO,这可能意味着您最终会有一个很大的堆栈深度。
因此,使用循环:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9],
o = {a:1, b:2, c:3, d:10, e:11, f:12, g:7, h:8, i:9};
function matched(i, j) {
return a[i]===o[j];
}
// Get the property names in `o`, and start at the beginning
var keys = Object.keys(o);
var i = 0;
var keyIndex = 0;
tick();
function tick() {
var match = findNextMatch();
if (match) {
console.log(match);
setTimeout(tick, 1000);
}
}
function findNextMatch() {
var j;
var match;
while (!match && i < a.length) {
j = keys[keyIndex];
if (matched(i, j)) {
match = a[i];
}
// Move to the next entry in our nested loops
if (++keyIndex >= keys.length) {
keyIndex = 0;
++i;
}
}
return match;
}
实际上,对我来说,这似乎更干净,即使没有深层次的关注。
发布于 2016-09-19 08:20:47
解决方案相对简单:
收集结果时,不要担心日志记录。相反,将所有结果存储在一个新数组中。
然后,使用延迟遍历该result数组:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9],
o = {a:1, b:2, c:3, d:10, e:11, f:12, g:7, h:8, i:9},
result = [];
function matched(i, j) {
return a[i]===o[j];
}
for (var i=0; i<a.length; ++i) {
for (var j in o) {
if (matched(i, j))
result.push(a[i]); // Store the found result.
}
}
var i = 0,
length = result.length;
(function iterator() {
console.log(result[i]); // Log the current result
if(++i < length) { // If there are more entries in the array
setTimeout(iterator, 1000); // Log the next entry in 1 second.
}
})();
发布于 2016-09-19 08:21:08
获取代码,但将输出更改为push,以另一个(全局)数组。然后使用计时器逐个打印数组内容。
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9],
o = {a:1, b:2, c:3, d:10, e:11, f:12, g:7, h:8, i:9},
t = [];
function matched(i, j) {
return a[i]===o[j];
}
// function to output first element of array
function output(){
if(t.length > 0){ // only generate output if array t isn't empty
console.log(t.shift());
setTimeout(output, 1000); // recall this function after 1s
}
}
for (var i=0; i<a.length; ++i) {
for (var j in o) {
if (matched(i, j)) t.push(a[i]); // store all found items inside the new array
}
}
output();https://stackoverflow.com/questions/39568321
复制相似问题